[Libreoffice-commits] core.git: Branch 'private/tml/fixwintext' - 3 commits - vcl/win
Tim Eves
tim_eves at sil.org
Mon Mar 14 05:23:34 UTC 2016
vcl/win/gdi/winlayout.cxx | 85 ++++++++++++++++++++--------------------------
1 file changed, 37 insertions(+), 48 deletions(-)
New commits:
commit 113cb32ea8aea71f39f9986736706dcb2ce47996
Author: Tim Eves <tim_eves at sil.org>
Date: Sat Mar 12 14:42:48 2016 +0700
Rename OpenGLGlyphChunk::mnAscent to mnBaselineOffset to reflect curr use
Changed at Tor's stuggestion to better describe to it's use as it's
value would be per chunk and based on the maximum ink box bounds of the
glyphs in the chunk, rather than having anything to do with the font's
real ascent value.
Change-Id: Iba15b26ff105731603b56f736cb9bca841f2cdd9
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 0c37bd6..a5d810c 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -81,7 +81,7 @@ struct OpenGLGlyphCacheChunk
std::vector<Rectangle> maLocation;
std::vector<int> maLeftOverhangs;
std::shared_ptr<OpenGLTexture> mpTexture;
- int mnAscent;
+ int mnBaselineOffset;
int mnHeight;
bool mbVertical;
bool mbRealGlyphIndices;
@@ -298,7 +298,7 @@ void DumpGlyphBitmap(HDC hDC, const OpenGLGlyphCacheChunk& rChunk)
std::ostringstream sLine("\n", std::ios_base::ate);
for (long y = 0; y < aBitmap.bmHeight; y++)
{
- if (y == rChunk.mnAscent + rChunk.getExtraOffset())
+ if (y == rChunk.mnBaselineOffset + rChunk.getExtraOffset())
sLine << "-";
else
sLine << ColorFor(GetPixel(hDC, 0, y));
@@ -444,14 +444,14 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
// bounds.Top() is the offset from the baseline at (0,0) to the top of the
// inkbox.
- aChunk.mnAscent = -bounds.Top();
+ aChunk.mnBaselineOffset = -bounds.Top();
aChunk.mnHeight = bounds.getHeight();
aChunk.mbVertical = false;
/*
DWRITE_FONT_METRICS aFontMetrics;
pTxt->GetFontFace()->GetMetrics(&aFontMetrics);
- aChunk.mnAscent = aFontMetrics.ascent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
- aChunk.mnHeight = aChunk.mnAscent + aFontMetrics.descent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
+ aChunk.mnBaselineOffset = aFontMetrics.ascent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
+ aChunk.mnHeight = aChunk.mnBaselineOffset + aFontMetrics.descent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
*/
@@ -524,7 +524,7 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
return false;
}
- D2D1_POINT_2F baseline = { aChunk.getExtraOffset(), aChunk.getExtraOffset() + aChunk.mnAscent };
+ D2D1_POINT_2F baseline = { aChunk.getExtraOffset(), aChunk.getExtraOffset() + aChunk.mnBaselineOffset };
DWRITE_GLYPH_RUN glyphs = {
pTxt->GetFontFace(),
pTxt->GetEmHeight(),
@@ -612,7 +612,7 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
DeleteDC(hDC);
return false;
}
- aChunk.mnAscent = aTextMetric.tmAscent;
+ aChunk.mnBaselineOffset = aTextMetric.tmAscent;
aChunk.mnHeight = aTextMetric.tmHeight;
LOGFONTW aLogfont;
@@ -1753,7 +1753,7 @@ 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() + rChunk.maLeftOverhangs[n],
- aPos.Y() - rChunk.mnAscent - rChunk.getExtraOffset(),
+ aPos.Y() - rChunk.mnBaselineOffset - rChunk.getExtraOffset(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ???
pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects);
@@ -3284,7 +3284,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(),
nAdvance + aPos.X() + mpGlyphOffsets[i].du - rChunk.getExtraOffset() + rChunk.maLeftOverhangs[n],
- aPos.Y() + mpGlyphOffsets[i].dv - rChunk.mnAscent - rChunk.getExtraOffset(),
+ aPos.Y() + mpGlyphOffsets[i].dv - rChunk.mnBaselineOffset - rChunk.getExtraOffset(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ???
pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects);
}
commit 4bb174633b93d6d881266c157f9bad5d085aedf5
Author: Tim Eves <tim_eves at sil.org>
Date: Sat Mar 12 14:34:09 2016 +0700
Fix horizontal occsional alingment issues in OpenGL cached glyphs
The left edge of the src location rectangle for the first glyph in a
cache chunk would set to extraspace and not zero, but all other
rectangles in the chunk would be set from the aEnds array. This produced
a bug where only certain letters would be mispositioned, proportional to
the fonts point size.
Change-Id: Id53b4a13d6d1534fc189fcd05ade77f1b7f90578
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index a2372a9..0c37bd6 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -298,7 +298,7 @@ void DumpGlyphBitmap(HDC hDC, const OpenGLGlyphCacheChunk& rChunk)
std::ostringstream sLine("\n", std::ios_base::ate);
for (long y = 0; y < aBitmap.bmHeight; y++)
{
- if (y == rChunk.mnAscent)
+ if (y == rChunk.mnAscent + rChunk.getExtraOffset())
sLine << "-";
else
sLine << ColorFor(GetPixel(hDC, 0, y));
@@ -444,9 +444,16 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
// bounds.Top() is the offset from the baseline at (0,0) to the top of the
// inkbox.
- aChunk.mnAscent = -bounds.Top() + 1;
- aChunk.mnHeight = bounds.GetHeight();
+ aChunk.mnAscent = -bounds.Top();
+ aChunk.mnHeight = bounds.getHeight();
aChunk.mbVertical = false;
+ /*
+ DWRITE_FONT_METRICS aFontMetrics;
+ pTxt->GetFontFace()->GetMetrics(&aFontMetrics);
+ aChunk.mnAscent = aFontMetrics.ascent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
+ aChunk.mnHeight = aChunk.mnAscent + aFontMetrics.descent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
+ */
+
aChunk.maLeftOverhangs.resize(nCount);
aChunk.maLocation.resize(nCount);
@@ -458,13 +465,11 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
std::vector<float> aGlyphAdv(nCount); // offsets between glyphs
std::vector<DWRITE_GLYPH_OFFSET> aGlyphOffset(nCount, DWRITE_GLYPH_OFFSET{0.0f,0.0f});
std::vector<int> aEnds(nCount); // end of each glyph box
- int lastOverhang = 0;
- int lastBlackWidth = 0;
float totWidth = 0;
for (int i = 0; i < nCount; ++i)
{
int overhang = aInkBoxes[i].Left();
- int blackWidth = aInkBoxes[i].GetWidth(); // width of non-AA pixels
+ int blackWidth = aInkBoxes[i].getWidth(); // width of non-AA pixels
aChunk.maLeftOverhangs[i] = overhang;
aGlyphAdv[i] = blackWidth + aChunk.getExtraSpace();
@@ -472,20 +477,14 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
totWidth += aGlyphAdv[i];
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 ?
}
// Leave extra space also at top and bottom
int nBitmapWidth = totWidth,
- nBitmapHeight = bounds.GetHeight() + aChunk.getExtraSpace();
+ nBitmapHeight = bounds.getHeight() + aChunk.getExtraSpace();
aChunk.maLocation.resize(nCount);
- UINT nPos = aChunk.getExtraOffset();
+ UINT nPos = 0;
for (int i = 0; i < nCount; i++)
{
// FIXME: really I don't get why 'vertical' makes any difference [!] what does it mean !?
@@ -501,7 +500,7 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
aChunk.maLocation[i].Left() = nPos;
aChunk.maLocation[i].Right() = aEnds[i];
aChunk.maLocation[i].Top() = 0;
- aChunk.maLocation[i].Bottom() = bounds.GetHeight() + aChunk.getExtraSpace();
+ aChunk.maLocation[i].Bottom() = bounds.getHeight() + aChunk.getExtraSpace();
}
nPos = aEnds[i];
}
@@ -4118,24 +4117,26 @@ std::vector<Rectangle> D2DWriteTextOutRenderer::GetGlyphInkBoxes(uint16_t * pGid
DWRITE_FONT_METRICS aFontMetrics;
mpFontFace->GetMetrics(&aFontMetrics);
- std::unique_ptr<DWRITE_GLYPH_METRICS> metrics(new DWRITE_GLYPH_METRICS[nGlyphs]);
- if (!SUCCEEDED(mpFontFace->GetDesignGlyphMetrics(pGid, nGlyphs, metrics.get(), false)))
+ std::vector<DWRITE_GLYPH_METRICS> metrics(nGlyphs);
+ if (!SUCCEEDED(mpFontFace->GetDesignGlyphMetrics(pGid, nGlyphs, metrics.data(), false)))
return std::vector<Rectangle>();
std::vector<Rectangle> aOut(nGlyphs);
auto pOut = aOut.begin();
- for (auto m = metrics.get(); nGlyphs; --nGlyphs, ++m, ++pOut)
+ for (auto &m : metrics)
{
- const long left = m->leftSideBearing,
- top = m->topSideBearing - m->verticalOriginY,
- right = m->advanceWidth - m->rightSideBearing,
- bottom = INT32(m->advanceHeight) - m->verticalOriginY - m->bottomSideBearing;
+ const long left = m.leftSideBearing,
+ top = m.topSideBearing - m.verticalOriginY,
+ right = m.advanceWidth - m.rightSideBearing,
+ bottom = INT32(m.advanceHeight) - m.verticalOriginY - m.bottomSideBearing;
// Scale to screen space.
- pOut->Left() = std::lround(left * mlfEmHeight / aFontMetrics.designUnitsPerEm);
- pOut->Top() = std::lround(top * mlfEmHeight / aFontMetrics.designUnitsPerEm);
- pOut->Right() = 1 + std::lround(right * mlfEmHeight / aFontMetrics.designUnitsPerEm);
- pOut->Bottom() = 1 + std::lround(bottom * mlfEmHeight / aFontMetrics.designUnitsPerEm);
+ pOut->Left() = std::lround(left * mlfEmHeight / aFontMetrics.designUnitsPerEm);
+ pOut->Top() = std::lround(top * mlfEmHeight / aFontMetrics.designUnitsPerEm);
+ pOut->Right() = std::lround(right * mlfEmHeight / aFontMetrics.designUnitsPerEm);
+ pOut->Bottom() = std::lround(bottom * mlfEmHeight / aFontMetrics.designUnitsPerEm);
+
+ ++pOut;
}
return aOut;
commit 1db4afc1da61ad025655df33906349acc64f8dc0
Author: Tim Eves <tim_eves at sil.org>
Date: Sat Mar 12 10:55:21 2016 +0700
Fix vertical alignment problems.
Inkboxes are returned with all co-ordinates relative to the glyphs
not the fonts ascent. Therefor bounds.Top() is not the vertical
overhang but the -ve height of the inkbox above the baseline.
This fixes the calulation of the per Chunk ascent.
Change-Id: I8f0135cfd84e7081ce154343085225ced25a56e0
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 8ae8926..a2372a9 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -442,22 +442,10 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
for (auto &box : aInkBoxes)
bounds.Union(box + Point(bounds.Right(), 0));
- // FIXME Glyphs can (and routinely do in non-Roman scripts) have inkboxes which extend
- // above and below the font's ascent and descent metrics. iI order to fix this we would
- // need to make the bitmap based on the actual bounds and calculate an ascent and descent
- // based on those, but I don't if that would break callers assumptions.
- DWRITE_FONT_METRICS aFontMetrics;
- pTxt->GetFontFace()->GetMetrics(&aFontMetrics);
- aChunk.mnAscent = aFontMetrics.ascent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
- // FIXME: Temporarily commented out, this positions glyphs vertically a bit better. But far from correctly.
- // aChunk.mnAscent += -bounds.Top();
+ // bounds.Top() is the offset from the baseline at (0,0) to the top of the
+ // inkbox.
+ aChunk.mnAscent = -bounds.Top() + 1;
aChunk.mnHeight = bounds.GetHeight();
- /*
- DWRITE_FONT_METRICS aFontMetrics;
- pTxt->GetFontFace()->GetMetrics(&aFontMetrics);
- aChunk.mnAscent = aFontMetrics.ascent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
- aChunk.mnHeight = aChunk.mnAscent + aFontMetrics.descent * pTxt->GetEmHeight() / aFontMetrics.designUnitsPerEm;
- */
aChunk.mbVertical = false;
aChunk.maLeftOverhangs.resize(nCount);
@@ -527,9 +515,6 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
aDC.fill(MAKE_SALCOLOR(0xff, 0xff, 0xff));
- int nY = aChunk.getExtraOffset();
- int nX = aChunk.getExtraOffset();
-
pTxt->BindDC(aDC.getCompatibleHDC(), Rectangle(0, 0, nBitmapWidth, nBitmapHeight));
auto pRT = pTxt->GetRenderTarget();
@@ -540,7 +525,7 @@ bool WinFontInstance::AddChunkOfGlyphs(bool bRealGlyphIndices, int nGlyphIndex,
return false;
}
- D2D1_POINT_2F baseline = { nX, nY - bounds.Top() };
+ D2D1_POINT_2F baseline = { aChunk.getExtraOffset(), aChunk.getExtraOffset() + aChunk.mnAscent };
DWRITE_GLYPH_RUN glyphs = {
pTxt->GetFontFace(),
pTxt->GetEmHeight(),
@@ -4119,7 +4104,10 @@ bool D2DWriteTextOutRenderer::ReleaseFont()
return true;
}
-
+// GetGlyphInkBoxes
+// The inkboxes returned have their origin on the baseline, to a -ve value
+// of Top() means the glyph extends abs(Top()) many pixels above the
+// baseline, and +ve means the ink starts that many pixels below.
std::vector<Rectangle> D2DWriteTextOutRenderer::GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const
{
Rectangle aExtent;
More information about the Libreoffice-commits
mailing list