1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/thebes/gfxGDIShaper.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,96 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +//#define FORCE_PR_LOG 1.10 + 1.11 +#include "gfxGDIShaper.h" 1.12 + 1.13 +/********************************************************************** 1.14 + * 1.15 + * class gfxGDIShaper 1.16 + * 1.17 + **********************************************************************/ 1.18 + 1.19 +bool 1.20 +gfxGDIShaper::ShapeText(gfxContext *aContext, 1.21 + const char16_t *aText, 1.22 + uint32_t aOffset, 1.23 + uint32_t aLength, 1.24 + int32_t aScript, 1.25 + gfxShapedText *aShapedText) 1.26 +{ 1.27 + DCFromContext dc(aContext); 1.28 + AutoSelectFont selectFont(dc, static_cast<gfxGDIFont*>(mFont)->GetHFONT()); 1.29 + 1.30 + uint32_t length = aLength; 1.31 + AutoFallibleTArray<WORD,500> glyphArray; 1.32 + if (!glyphArray.SetLength(length)) { 1.33 + return false; 1.34 + } 1.35 + WORD *glyphs = glyphArray.Elements(); 1.36 + 1.37 + DWORD ret = ::GetGlyphIndicesW(dc, char16ptr_t(aText), length, 1.38 + glyphs, GGI_MARK_NONEXISTING_GLYPHS); 1.39 + if (ret == GDI_ERROR) { 1.40 + return false; 1.41 + } 1.42 + 1.43 + for (int k = 0; k < length; k++) { 1.44 + if (glyphs[k] == 0xFFFF) 1.45 + return false; 1.46 + } 1.47 + 1.48 + SIZE size; 1.49 + AutoFallibleTArray<int,500> partialWidthArray; 1.50 + if (!partialWidthArray.SetLength(length)) { 1.51 + return false; 1.52 + } 1.53 + 1.54 + BOOL success = ::GetTextExtentExPointI(dc, 1.55 + glyphs, 1.56 + length, 1.57 + INT_MAX, 1.58 + nullptr, 1.59 + partialWidthArray.Elements(), 1.60 + &size); 1.61 + if (!success) { 1.62 + return false; 1.63 + } 1.64 + 1.65 + gfxTextRun::CompressedGlyph g; 1.66 + gfxTextRun::CompressedGlyph *charGlyphs = 1.67 + aShapedText->GetCharacterGlyphs(); 1.68 + uint32_t i; 1.69 + int32_t lastWidth = 0; 1.70 + int32_t appUnitsPerDevPixel = aShapedText->GetAppUnitsPerDevUnit(); 1.71 + for (i = 0; i < length; ++i) { 1.72 + uint32_t offset = aOffset + i; 1.73 + int32_t advancePixels = partialWidthArray[i] - lastWidth; 1.74 + lastWidth = partialWidthArray[i]; 1.75 + int32_t advanceAppUnits = advancePixels * appUnitsPerDevPixel; 1.76 + WCHAR glyph = glyphs[i]; 1.77 + NS_ASSERTION(!gfxFontGroup::IsInvalidChar(aText[i]), 1.78 + "Invalid character detected!"); 1.79 + bool atClusterStart = charGlyphs[offset].IsClusterStart(); 1.80 + if (advanceAppUnits >= 0 && 1.81 + gfxShapedWord::CompressedGlyph::IsSimpleAdvance(advanceAppUnits) && 1.82 + gfxShapedWord::CompressedGlyph::IsSimpleGlyphID(glyph) && 1.83 + atClusterStart) 1.84 + { 1.85 + charGlyphs[offset].SetSimpleGlyph(advanceAppUnits, glyph); 1.86 + } else { 1.87 + gfxShapedText::DetailedGlyph details; 1.88 + details.mGlyphID = glyph; 1.89 + details.mAdvance = advanceAppUnits; 1.90 + details.mXOffset = 0; 1.91 + details.mYOffset = 0; 1.92 + aShapedText->SetGlyphs(offset, 1.93 + g.SetComplex(atClusterStart, true, 1), 1.94 + &details); 1.95 + } 1.96 + } 1.97 + 1.98 + return true; 1.99 +}