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 blink {
     28 
     29 SVGTextMetrics::SVGTextMetrics()
     30     : m_width(0)
     31     , m_height(0)
     32     , m_length(0)
     33     , m_glyph(0)
     34 {
     35 }
     36 
     37 SVGTextMetrics::SVGTextMetrics(SVGTextMetrics::MetricsType)
     38     : m_width(0)
     39     , m_height(0)
     40     , m_length(1)
     41     , m_glyph(0)
     42 {
     43 }
     44 
     45 SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun& run)
     46 {
     47     ASSERT(textRenderer);
     48 
     49     float scalingFactor = textRenderer->scalingFactor();
     50     ASSERT(scalingFactor);
     51 
     52     const Font& scaledFont = textRenderer->scaledFont();
     53     int length = 0;
     54 
     55     // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
     56     m_width = scaledFont.width(run, length, m_glyph) / scalingFactor;
     57     m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
     58 
     59     ASSERT(length >= 0);
     60     m_length = static_cast<unsigned>(length);
     61 }
     62 
     63 TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length)
     64 {
     65     ASSERT(text->style());
     66     return constructTextRun(text, position, length, text->style()->direction());
     67 }
     68 
     69 TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length, TextDirection textDirection)
     70 {
     71     RenderStyle* style = text->style();
     72     ASSERT(style);
     73 
     74     TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero.
     75                 , 0 // length, will be set below if non-zero.
     76                 , 0 // xPos, only relevant with allowTabs=true
     77                 , 0 // padding, only relevant for justified text, not relevant for SVG
     78                 , TextRun::AllowTrailingExpansion
     79                 , textDirection
     80                 , isOverride(style->unicodeBidi()) /* directionalOverride */);
     81 
     82     if (length) {
     83         if (text->is8Bit())
     84             run.setText(text->characters8() + position, length);
     85         else
     86             run.setText(text->characters16() + position, length);
     87     }
     88 
     89     if (textRunNeedsRenderingContext(style->font()))
     90         run.setRenderingContext(SVGTextRunRenderingContext::create(text));
     91 
     92     // We handle letter & word spacing ourselves.
     93     run.disableSpacing();
     94 
     95     // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
     96     run.setCharactersLength(text->textLength() - position);
     97     ASSERT(run.charactersLength() >= run.length());
     98     return run;
     99 }
    100 
    101 SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length, TextDirection textDirection)
    102 {
    103     ASSERT(text);
    104     return SVGTextMetrics(text, constructTextRun(text, position, length, textDirection));
    105 }
    106 
    107 SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
    108 {
    109     ASSERT(text);
    110     return SVGTextMetrics(text, constructTextRun(text, position, length));
    111 }
    112 
    113 SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, Glyph glyphNameGlyphId)
    114 {
    115     ASSERT(text);
    116 
    117     bool needsContext = textRunNeedsRenderingContext(text->style()->font());
    118     float scalingFactor = text->scalingFactor();
    119     ASSERT(scalingFactor);
    120 
    121     m_width = width / scalingFactor;
    122     m_height = text->scaledFont().fontMetrics().floatHeight() / scalingFactor;
    123     m_glyph = needsContext ? glyphNameGlyphId : 0;
    124 
    125     m_length = length;
    126 }
    127 
    128 }
    129