Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 
     22 #include "core/rendering/svg/SVGTextMetrics.h"
     23 
     24 #include "core/rendering/svg/RenderSVGInlineText.h"
     25 #include "core/rendering/svg/SVGTextRunRenderingContext.h"
     26 
     27 namespace WebCore {
     28 
     29 SVGTextMetrics::SVGTextMetrics()
     30     : m_width(0)
     31     , m_height(0)
     32     , m_length(0)
     33 {
     34 }
     35 
     36 SVGTextMetrics::SVGTextMetrics(SVGTextMetrics::MetricsType)
     37     : m_width(0)
     38     , m_height(0)
     39     , m_length(1)
     40 {
     41 }
     42 
     43 SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun& run)
     44 {
     45     ASSERT(textRenderer);
     46 
     47     float scalingFactor = textRenderer->scalingFactor();
     48     ASSERT(scalingFactor);
     49 
     50     const Font& scaledFont = textRenderer->scaledFont();
     51     int length = 0;
     52 
     53     // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
     54     m_width = scaledFont.width(run, length, m_glyph.name) / scalingFactor;
     55     m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
     56 
     57     m_glyph.unicodeString = run.is8Bit() ? String(run.characters8(), length) : String(run.characters16(), length);
     58     m_glyph.isValid = true;
     59 
     60     ASSERT(length >= 0);
     61     m_length = static_cast<unsigned>(length);
     62 }
     63 
     64 TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length)
     65 {
     66     RenderStyle* style = text->style();
     67     ASSERT(style);
     68 
     69     TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero.
     70                 , 0 // length, will be set below if non-zero.
     71                 , 0 // xPos, only relevant with allowTabs=true
     72                 , 0 // padding, only relevant for justified text, not relevant for SVG
     73                 , TextRun::AllowTrailingExpansion
     74                 , style->direction()
     75                 , isOverride(style->unicodeBidi()) /* directionalOverride */);
     76 
     77     if (length) {
     78         if (text->is8Bit())
     79             run.setText(text->characters8() + position, length);
     80         else
     81             run.setText(text->characters16() + position, length);
     82     }
     83 
     84     if (textRunNeedsRenderingContext(style->font()))
     85         run.setRenderingContext(SVGTextRunRenderingContext::create(text));
     86 
     87     run.disableRoundingHacks();
     88 
     89     // We handle letter & word spacing ourselves.
     90     run.disableSpacing();
     91 
     92     // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
     93     run.setCharactersLength(text->textLength() - position);
     94     ASSERT(run.charactersLength() >= run.length());
     95     return run;
     96 }
     97 
     98 SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
     99 {
    100     ASSERT(text);
    101     return SVGTextMetrics(text, constructTextRun(text, position, length));
    102 }
    103 
    104 SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, const String& glyphName)
    105 {
    106     ASSERT(text);
    107 
    108     bool needsContext = textRunNeedsRenderingContext(text->style()->font());
    109     float scalingFactor = text->scalingFactor();
    110     ASSERT(scalingFactor);
    111 
    112     m_width = width / scalingFactor;
    113     m_height = text->scaledFont().fontMetrics().floatHeight() / scalingFactor;
    114     if (needsContext) {
    115         m_glyph.isValid = true;
    116         m_glyph.unicodeString = text->substring(position, length);
    117         m_glyph.name = glyphName;
    118     }
    119 
    120     m_length = length;
    121 }
    122 
    123 }
    124