gfx/thebes/gfxGDIShaper.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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 }

mercurial