Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2010. 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 #ifndef SVGTextFragment_h
     21 #define SVGTextFragment_h
     22 
     23 #if ENABLE(SVG)
     24 #include "AffineTransform.h"
     25 
     26 namespace WebCore {
     27 
     28 // A SVGTextFragment describes a text fragment of a RenderSVGInlineText which can be rendered at once.
     29 struct SVGTextFragment {
     30     SVGTextFragment()
     31         : characterOffset(0)
     32         , metricsListOffset(0)
     33         , length(0)
     34         , isTextOnPath(false)
     35         , x(0)
     36         , y(0)
     37         , width(0)
     38         , height(0)
     39     {
     40     }
     41 
     42     enum TransformType {
     43         TransformRespectingTextLength,
     44         TransformIgnoringTextLength
     45     };
     46 
     47     void buildFragmentTransform(AffineTransform& result, TransformType type = TransformRespectingTextLength) const
     48     {
     49         if (type == TransformIgnoringTextLength) {
     50             result = transform;
     51             transformAroundOrigin(result);
     52             return;
     53         }
     54 
     55         if (isTextOnPath)
     56             buildTransformForTextOnPath(result);
     57         else
     58             buildTransformForTextOnLine(result);
     59     }
     60 
     61     // The first rendered character starts at RenderSVGInlineText::characters() + characterOffset.
     62     unsigned characterOffset;
     63     unsigned metricsListOffset;
     64     unsigned length : 31;
     65     bool isTextOnPath : 1;
     66 
     67     float x;
     68     float y;
     69     float width;
     70     float height;
     71 
     72     // Includes rotation/glyph-orientation-(horizontal|vertical) transforms, as well as orientation related shifts
     73     // (see SVGTextLayoutEngine, which builds this transformation).
     74     AffineTransform transform;
     75 
     76     // Contains lengthAdjust related transformations, which are not allowd to influence the SVGTextQuery code.
     77     AffineTransform lengthAdjustTransform;
     78 
     79 private:
     80     void transformAroundOrigin(AffineTransform& result) const
     81     {
     82         // Returns (translate(x, y) * result) * translate(-x, -y).
     83         result.setE(result.e() + x);
     84         result.setF(result.f() + y);
     85         result.translate(-x, -y);
     86     }
     87 
     88     void buildTransformForTextOnPath(AffineTransform& result) const
     89     {
     90         // For text-on-path layout, multiply the transform with the lengthAdjustTransform before orienting the resulting transform.
     91         result = lengthAdjustTransform.isIdentity() ? transform : transform * lengthAdjustTransform;
     92         if (!result.isIdentity())
     93             transformAroundOrigin(result);
     94     }
     95 
     96     void buildTransformForTextOnLine(AffineTransform& result) const
     97     {
     98         // For text-on-line layout, orient the transform first, then multiply the lengthAdjustTransform with the oriented transform.
     99         if (transform.isIdentity()) {
    100             result = lengthAdjustTransform;
    101             return;
    102         }
    103 
    104         result = transform;
    105         transformAroundOrigin(result);
    106 
    107         if (!lengthAdjustTransform.isIdentity())
    108             result = lengthAdjustTransform * result;
    109     }
    110 };
    111 
    112 } // namespace WebCore
    113 
    114 #endif // ENABLE(SVG)
    115 #endif
    116