summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2016-02-23 16:45:21 +0000
committerTor Lillqvist <tml@collabora.com>2016-03-11 08:14:37 +0200
commit3163bd9a12a8037eaadb5b7449523e06772f2c0f (patch)
treeaabb3e4c6725464a6c92ad9386af0080f8d1ab81
parent42d6a165b053ebdccbd6979eb849b1abe305d2ba (diff)
Starting to render horizontal text apparently correctly ...
Change-Id: I6bf049bf56bc971824c9591ccd23e437b9b268b3
-rw-r--r--vcl/win/gdi/winlayout.cxx138
1 files changed, 83 insertions, 55 deletions
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 31168bc78909..8e479ebc1dc2 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -78,6 +78,7 @@ struct OpenGLGlyphCacheChunk
WORD mnFirstGlyph;
int mnGlyphCount;
std::vector<Rectangle> maLocation;
+ std::vector<int> maLeftOverhangs;
std::shared_ptr<OpenGLTexture> mpTexture;
int mnAscent;
int mnHeight;
@@ -335,10 +336,12 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
}
}
- std::ostringstream sLine;
- for (int i = 0; i < nCount; i++)
- sLine << aABC[i].abcA << ":" << aABC[i].abcB << ":" << aABC[i].abcC << " ";
- SAL_INFO("vcl.gdi.opengl", "ABC widths: " << sLine.str());
+ {
+ std::ostringstream sLine;
+ for (int i = 0; i < nCount; i++)
+ sLine << aABC[i].abcA << ":" << aABC[i].abcB << ":" << aABC[i].abcC << " ";
+ SAL_INFO("vcl.gdi.opengl", "ABC widths: " << sLine.str());
+ }
TEXTMETRICW aTextMetric;
if (!GetTextMetricsW(hDC, &aTextMetric))
@@ -351,23 +354,6 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
aChunk.mnAscent = aTextMetric.tmAscent;
aChunk.mnHeight = aTextMetric.tmHeight;
- // Try hard to avoid overlap as we want to be able to use
- // individual rectangles for each glyph. The ABC widths don't
- // take anti-aliasing into consideration. Let's hope that leaving
- // "extra" space between glyphs will help.
- std::vector<int> aDX(nCount);
- int totWidth = 0;
- for (int i = 0; i < nCount; i++)
- {
- aDX[i] = aABC[i].abcB + std::abs(aABC[i].abcC);
- if (i == 0)
- aDX[0] += std::abs(aABC[0].abcA);
- if (i < nCount-1)
- aDX[i] += std::abs(aABC[i+1].abcA);
- aDX[i] += aChunk.getExtraSpace();
- totWidth += aDX[i];
- }
-
LOGFONTW aLogfont;
if (!GetObjectW(rLayout.mhFont, sizeof(aLogfont), &aLogfont))
{
@@ -387,18 +373,49 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
return false;
}
- SAL_INFO("vcl.gdi.opengl", OUString(sFaceName, nFaceNameLen) <<
- ": Escapement=" << aLogfont.lfEscapement <<
- " Orientation=" << aLogfont.lfOrientation <<
- " Ascent=" << aTextMetric.tmAscent <<
- " InternalLeading=" << aTextMetric.tmInternalLeading <<
- " Size=(" << aSize.cx << "," << aSize.cy << ") totWidth=" << totWidth);
-
if (SelectObject(hDC, hOrigFont) == NULL)
SAL_WARN("vcl.gdi", "SelectObject failed: " << WindowsErrorString(GetLastError()));
if (!DeleteDC(hDC))
SAL_WARN("vcl.gdi", "DeleteDC failed: " << WindowsErrorString(GetLastError()));
+ // Offset between glyph positions
+ aChunk.maLeftOverhangs.resize(nCount);
+
+ // Try hard to avoid overlap as we want to be able to use
+ // individual rectangles for each glyph. The ABC widths don't
+ // take anti-aliasing into consideration. Let's hope that leaving
+ // "extra" space between glyphs will help.
+ std::vector<int> aDX(nCount); // offsets between glyphs
+ std::vector<int> aEnds(nCount); // end of each glyph box
+ int totWidth = 0;
+ int lastOverhang = 0;
+ int lastBlackWidth = 0;
+ for (int i = 0; i < nCount; i++)
+ {
+ int overhang = aABC[i].abcA;
+ int blackWidth = aABC[i].abcB; // width of non-AA pixels
+ aChunk.maLeftOverhangs[i] = overhang;
+
+ if (i > 0)
+ aDX[i - 1] += aChunk.getExtraSpace() + lastOverhang - overhang + lastBlackWidth;
+
+ totWidth += blackWidth + aChunk.getExtraSpace();
+ aEnds[i] = totWidth;
+
+ lastOverhang = overhang;
+ lastBlackWidth = blackWidth;
+ // FIXME: for vertical text - this is completely horked I guess [!]
+ // or does A and C have a different meaning there that is
+ // consistent somehow ?
+ }
+
+ SAL_INFO("vcl.gdi.opengl", OUString(sFaceName, nFaceNameLen) <<
+ ": Escapement=" << aLogfont.lfEscapement <<
+ " Orientation=" << aLogfont.lfOrientation <<
+ " Ascent=" << aTextMetric.tmAscent <<
+ " InternalLeading=" << aTextMetric.tmInternalLeading <<
+ " Size=(" << aSize.cx << "," << aSize.cy << ") totWidth=" << totWidth);
+
// Leave extra space also at top and bottom
int nBitmapWidth, nBitmapHeight;
if (sFaceName[0] == '@')
@@ -418,6 +435,28 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
if (aChunk.mbVertical || aLogfont.lfEscapement != 0)
return false;
+ aChunk.maLocation.resize(nCount);
+ UINT nPos = 0;
+ for (int i = 0; i < nCount; i++)
+ {
+ // FIXME: really I don't get why 'vertical' make sany difference [!] what does it mean !?
+ if (aChunk.mbVertical)
+ {
+ aChunk.maLocation[i].Left() = 0;
+ aChunk.maLocation[i].Right() = nBitmapWidth;
+ aChunk.maLocation[i].Top() = nPos;
+ aChunk.maLocation[i].Bottom() = nPos + aDX[i] + aChunk.maLeftOverhangs[i];
+ }
+ else
+ {
+ aChunk.maLocation[i].Left() = nPos;
+ aChunk.maLocation[i].Right() = aEnds[i];
+ aChunk.maLocation[i].Top() = 0;
+ aChunk.maLocation[i].Bottom() = aSize.cy + aChunk.getExtraSpace();
+ }
+ nPos = aEnds[i];
+ }
+
OpenGLCompatibleDC aDC(rGraphics, 0, 0, nBitmapWidth, nBitmapHeight);
HFONT hNonAntialiasedFont = NULL;
@@ -448,10 +487,12 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
aDC.fill(MAKE_SALCOLOR(0xff, 0xff, 0xff));
- int nY = aChunk.getExtraOffset();
- int nX = nY;
+ int nY = aChunk.getExtraOffset();
+ int nX = nY;
if (aChunk.mbVertical)
nX += aDX[0];
+ else
+ nX -= aABC[0].abcA;
if (!ExtTextOutW(aDC.getCompatibleHDC(),
nX, nY,
bRealGlyphIndices ? ETO_GLYPH_INDEX : 0,
@@ -466,28 +507,6 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
return false;
}
- aChunk.maLocation.resize(nCount);
- UINT nPos = 0;
- for (int i = 0; i < nCount; i++)
- {
- if (aChunk.mbVertical)
- {
- aChunk.maLocation[i].Left() = 0;
- aChunk.maLocation[i].Right() = nBitmapWidth;
- aChunk.maLocation[i].Top() = nPos;
- aChunk.maLocation[i].Bottom() = nPos + aDX[i];
- nPos = aChunk.maLocation[i].Bottom();
- }
- else
- {
- aChunk.maLocation[i].Left() = nPos;
- aChunk.maLocation[i].Right() = nPos + aDX[i];
- nPos = aChunk.maLocation[i].Right();
- aChunk.maLocation[i].Top() = 0;
- aChunk.maLocation[i].Bottom() = aSize.cy + aChunk.getExtraSpace();
- }
- }
-
aChunk.mpTexture = std::unique_ptr<OpenGLTexture>(aDC.getTexture());
maOpenGLGlyphCache.insert(n, aChunk);
@@ -499,6 +518,13 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
#ifdef SAL_LOG_INFO
SAL_INFO("vcl.gdi.opengl", "this=" << this << " now: " << maOpenGLGlyphCache);
DumpGlyphBitmap(aDC.getCompatibleHDC());
+
+ {
+ std::ostringstream sLine;
+ for (int i = 0; i < nCount; i++)
+ sLine << aDX[i] << ":" << aChunk.maLeftOverhangs[i] << " ";
+ SAL_INFO("vcl.gdi.opengl", "DX:offset : " << sLine.str());
+ }
#endif
return true;
@@ -1465,7 +1491,8 @@ bool SimpleWinLayout::DrawCachedGlyphs(SalGraphics& rGraphics) const
SalTwoRect a2Rects(rChunk.maLocation[n].Left(), rChunk.maLocation[n].Top(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight(),
- nAdvance + aPos.X() - rChunk.getExtraOffset(), aPos.Y() - rChunk.mnAscent - rChunk.getExtraOffset(),
+ nAdvance + aPos.X() - rChunk.getExtraOffset() + rChunk.maLeftOverhangs[n],
+ aPos.Y() - rChunk.mnAscent - rChunk.getExtraOffset(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ???
pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects);
@@ -2987,7 +3014,7 @@ bool UniscribeLayout::DrawCachedGlyphsUsingTextures(SalGraphics& rGraphics) cons
{
SalTwoRect a2Rects(rChunk.maLocation[n].Left(), rChunk.maLocation[n].Top(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight(),
- aPos.X(), nAdvance + aPos.Y(),
+ aPos.X() + rChunk.maLeftOverhangs[n], nAdvance + aPos.Y(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ???
pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects);
}
@@ -2995,7 +3022,8 @@ bool UniscribeLayout::DrawCachedGlyphsUsingTextures(SalGraphics& rGraphics) cons
{
SalTwoRect a2Rects(rChunk.maLocation[n].Left(), rChunk.maLocation[n].Top(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight(),
- nAdvance + aPos.X() + mpGlyphOffsets[i].du - rChunk.getExtraOffset(), aPos.Y() + mpGlyphOffsets[i].dv - rChunk.mnAscent - rChunk.getExtraOffset(),
+ nAdvance + aPos.X() + mpGlyphOffsets[i].du - rChunk.getExtraOffset() + rChunk.maLeftOverhangs[n],
+ aPos.Y() + mpGlyphOffsets[i].dv - rChunk.mnAscent - rChunk.getExtraOffset(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ???
pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects);
}