Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 //#define FORCE_PR_LOG
8 #include "gfxGDIShaper.h"
10 /**********************************************************************
11 *
12 * class gfxGDIShaper
13 *
14 **********************************************************************/
16 bool
17 gfxGDIShaper::ShapeText(gfxContext *aContext,
18 const char16_t *aText,
19 uint32_t aOffset,
20 uint32_t aLength,
21 int32_t aScript,
22 gfxShapedText *aShapedText)
23 {
24 DCFromContext dc(aContext);
25 AutoSelectFont selectFont(dc, static_cast<gfxGDIFont*>(mFont)->GetHFONT());
27 uint32_t length = aLength;
28 AutoFallibleTArray<WORD,500> glyphArray;
29 if (!glyphArray.SetLength(length)) {
30 return false;
31 }
32 WORD *glyphs = glyphArray.Elements();
34 DWORD ret = ::GetGlyphIndicesW(dc, char16ptr_t(aText), length,
35 glyphs, GGI_MARK_NONEXISTING_GLYPHS);
36 if (ret == GDI_ERROR) {
37 return false;
38 }
40 for (int k = 0; k < length; k++) {
41 if (glyphs[k] == 0xFFFF)
42 return false;
43 }
45 SIZE size;
46 AutoFallibleTArray<int,500> partialWidthArray;
47 if (!partialWidthArray.SetLength(length)) {
48 return false;
49 }
51 BOOL success = ::GetTextExtentExPointI(dc,
52 glyphs,
53 length,
54 INT_MAX,
55 nullptr,
56 partialWidthArray.Elements(),
57 &size);
58 if (!success) {
59 return false;
60 }
62 gfxTextRun::CompressedGlyph g;
63 gfxTextRun::CompressedGlyph *charGlyphs =
64 aShapedText->GetCharacterGlyphs();
65 uint32_t i;
66 int32_t lastWidth = 0;
67 int32_t appUnitsPerDevPixel = aShapedText->GetAppUnitsPerDevUnit();
68 for (i = 0; i < length; ++i) {
69 uint32_t offset = aOffset + i;
70 int32_t advancePixels = partialWidthArray[i] - lastWidth;
71 lastWidth = partialWidthArray[i];
72 int32_t advanceAppUnits = advancePixels * appUnitsPerDevPixel;
73 WCHAR glyph = glyphs[i];
74 NS_ASSERTION(!gfxFontGroup::IsInvalidChar(aText[i]),
75 "Invalid character detected!");
76 bool atClusterStart = charGlyphs[offset].IsClusterStart();
77 if (advanceAppUnits >= 0 &&
78 gfxShapedWord::CompressedGlyph::IsSimpleAdvance(advanceAppUnits) &&
79 gfxShapedWord::CompressedGlyph::IsSimpleGlyphID(glyph) &&
80 atClusterStart)
81 {
82 charGlyphs[offset].SetSimpleGlyph(advanceAppUnits, glyph);
83 } else {
84 gfxShapedText::DetailedGlyph details;
85 details.mGlyphID = glyph;
86 details.mAdvance = advanceAppUnits;
87 details.mXOffset = 0;
88 details.mYOffset = 0;
89 aShapedText->SetGlyphs(offset,
90 g.SetComplex(atClusterStart, true, 1),
91 &details);
92 }
93 }
95 return true;
96 }