[Konsole-devel] [Bug 59162] Fixed width font alignment problems for Japanese (and other languages I suspect)

Ken Deeter ktdeeter at alumni.princeton.edu
Sun Jun 1 01:47:39 UTC 2003


>
> It basically makes that konsole draws character by character, regardless of
> the font choosen. This should get turned on automatically when konsole
> detects a font with variable width western glyphs.
>

I tried what you suggested, and it still didn't work. I found an error
in the rendering code for non-fixed width case however.

The original code (in kde 3.1.2) looks like this. It happens on line 456 of
TEWidget.cpp. It also happens a bit later and it looks like it is copy & pasted
so the same error happens there.

     if(!fixed_font)
     {
       // The meaning of y differs between different versions of QPainter::drawText!!
       int y = rect.y(); // top of rect
       for(unsigned int i=0;i<str.length();i++)
       {
         drawstr = str.at(i);
         // Add double of the width if next c is 0;
         int w = (attr+i+1)->c ? font_w : font_w * 2;
         paint.drawText(x,y, w, font_h, Qt::AlignHCenter | Qt::DontClip, drawstr, -1);
         x += w;
       }
     }


Anyhow, the problem with this is that the value of i is used both to
index into the string and the attr array. For the string, the index
refers to the character (and each double width character is considered
only one) where as the attr array will have a two spaces for each
double width character. So the problem was happening when these two
indeces get out of sync, you get some double width characters drawn as
single width, and some single width drawn as double width.

On my local machine, I replaced this code segment (and the one that occurs
a little later) with a call to something that looks like:

static void drawNonFixed(QPainter &paint, QRect rect, QString& str, const ca* attr,
                         int x, int font_w, int font_h)
{
      QString drawstr;
      int y = rect.y(); // top of rect
      int nc = 0; // current offset into the attr array
      for(unsigned int i=0;i<str.length();i++)
      {
        drawstr = str.at(i);
        // Add double of the width if next c is 0;
        int w = font_w;
        if (!(attr+nc+1)->c) {
          w = font_w * 2;
          nc++ ; // we're looking at a double width character, so compensate
                 // index into the attr array
        }
        //int w = (attr+i+1)->c ? font_w : font_w * 2;
        paint.drawText(x,y, w, font_h, Qt::AlignHCenter | Qt::DontClip, drawstr, -1)
;
        x += w;
        nc++;
      }
}

Basically, we keep a different index called nc, for the attr
array. When we see a double width character, we increment nc by an
extra one, so that during the next iteration, the right index will be
used to check whether the current character is double width.

This makes everything work fine and dandy.

As for the fonts getting all spaced out when I choose Kochi Gothic or similar,
I'm guessing this is a Qt bug? (it looks messed up in the font dialog as well)


Also, the "fixed_font" value needs something in the gui so that it can
be overridden. Something like a checkbox saying "treat fonts as
proportional" or something.

Either that, or we need to do an extra check to make sure double width characters
in the current font have exactly twice the width of those in the REPCHAR array.

Hopefully you can take the modified code and work it in somehow. I'd love to
see it fixed in the next stable release. (are there plans for 3.1.3?)


I'll attach my modified TEWidget.cpp for your reference, though I don't think
adding a static function is probably the best answer, more likely
it should be made into a private function.




-------------- next part --------------
A non-text attachment was scrubbed...
Name: TEWidget.cpp.gz
Type: application/x-gzip
Size: 15890 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/konsole-devel/attachments/20030531/2ecb6897/attachment.gz>


More information about the konsole-devel mailing list