vcl/win/gdi/winlayout.cxx | 85 ++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 48 deletions(-)
New commits: commit 113cb32ea8aea71f39f9986736706dcb2ce47996 Author: Tim Eves <tim_e...@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_e...@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_e...@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; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits