| /* |
| * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "third_party/blink/renderer/core/layout/svg/svg_text_layout_engine_baseline.h" |
| |
| #include "third_party/blink/renderer/core/style/svg_computed_style.h" |
| #include "third_party/blink/renderer/core/svg/svg_length_context.h" |
| #include "third_party/blink/renderer/platform/fonts/font.h" |
| |
| namespace blink { |
| |
| SVGTextLayoutEngineBaseline::SVGTextLayoutEngineBaseline(const Font& font, |
| float effective_zoom) |
| : font_(font), effective_zoom_(effective_zoom) { |
| DCHECK(effective_zoom_); |
| } |
| |
| float SVGTextLayoutEngineBaseline::CalculateBaselineShift( |
| const ComputedStyle& style) const { |
| const SVGComputedStyle& svg_style = style.SvgStyle(); |
| const SimpleFontData* font_data = font_.PrimaryFont(); |
| DCHECK(font_data); |
| if (!font_data) |
| return 0; |
| |
| DCHECK(effective_zoom_); |
| switch (svg_style.BaselineShift()) { |
| case BS_LENGTH: |
| return SVGLengthContext::ValueForLength( |
| svg_style.BaselineShiftValue(), style, |
| font_.GetFontDescription().ComputedPixelSize() / effective_zoom_); |
| case BS_SUB: |
| return -font_data->GetFontMetrics().FloatHeight() / 2 / effective_zoom_; |
| case BS_SUPER: |
| return font_data->GetFontMetrics().FloatHeight() / 2 / effective_zoom_; |
| default: |
| NOTREACHED(); |
| return 0; |
| } |
| } |
| |
| EAlignmentBaseline |
| SVGTextLayoutEngineBaseline::DominantBaselineToAlignmentBaseline( |
| bool is_vertical_text, |
| LineLayoutItem text_line_layout) const { |
| DCHECK(text_line_layout); |
| DCHECK(text_line_layout.Style()); |
| |
| const SVGComputedStyle& style = text_line_layout.StyleRef().SvgStyle(); |
| |
| EDominantBaseline baseline = style.DominantBaseline(); |
| if (baseline == DB_AUTO) { |
| if (is_vertical_text) |
| baseline = DB_CENTRAL; |
| else |
| baseline = DB_ALPHABETIC; |
| } |
| |
| switch (baseline) { |
| case DB_USE_SCRIPT: |
| // TODO(fs): The dominant-baseline and the baseline-table components |
| // are set by determining the predominant script of the character data |
| // content. |
| return AB_ALPHABETIC; |
| case DB_NO_CHANGE: |
| DCHECK(text_line_layout.Parent()); |
| return DominantBaselineToAlignmentBaseline(is_vertical_text, |
| text_line_layout.Parent()); |
| case DB_RESET_SIZE: |
| DCHECK(text_line_layout.Parent()); |
| return DominantBaselineToAlignmentBaseline(is_vertical_text, |
| text_line_layout.Parent()); |
| case DB_IDEOGRAPHIC: |
| return AB_IDEOGRAPHIC; |
| case DB_ALPHABETIC: |
| return AB_ALPHABETIC; |
| case DB_HANGING: |
| return AB_HANGING; |
| case DB_MATHEMATICAL: |
| return AB_MATHEMATICAL; |
| case DB_CENTRAL: |
| return AB_CENTRAL; |
| case DB_MIDDLE: |
| return AB_MIDDLE; |
| case DB_TEXT_AFTER_EDGE: |
| return AB_TEXT_AFTER_EDGE; |
| case DB_TEXT_BEFORE_EDGE: |
| return AB_TEXT_BEFORE_EDGE; |
| default: |
| NOTREACHED(); |
| return AB_AUTO; |
| } |
| } |
| |
| float SVGTextLayoutEngineBaseline::CalculateAlignmentBaselineShift( |
| bool is_vertical_text, |
| LineLayoutItem text_line_layout) const { |
| DCHECK(text_line_layout); |
| DCHECK(text_line_layout.Style()); |
| DCHECK(text_line_layout.Parent()); |
| |
| LineLayoutItem text_line_layout_parent = text_line_layout.Parent(); |
| DCHECK(text_line_layout_parent); |
| |
| EAlignmentBaseline baseline = |
| text_line_layout.StyleRef().SvgStyle().AlignmentBaseline(); |
| if (baseline == AB_AUTO || baseline == AB_BASELINE) { |
| baseline = DominantBaselineToAlignmentBaseline(is_vertical_text, |
| text_line_layout_parent); |
| DCHECK_NE(baseline, AB_AUTO); |
| DCHECK_NE(baseline, AB_BASELINE); |
| } |
| |
| const SimpleFontData* font_data = font_.PrimaryFont(); |
| DCHECK(font_data); |
| if (!font_data) |
| return 0; |
| |
| const FontMetrics& font_metrics = font_data->GetFontMetrics(); |
| float ascent = font_metrics.FloatAscent() / effective_zoom_; |
| float descent = font_metrics.FloatDescent() / effective_zoom_; |
| float xheight = font_metrics.XHeight() / effective_zoom_; |
| |
| // Note: http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling |
| switch (baseline) { |
| case AB_BEFORE_EDGE: |
| case AB_TEXT_BEFORE_EDGE: |
| return ascent; |
| case AB_MIDDLE: |
| return xheight / 2; |
| case AB_CENTRAL: |
| return (ascent - descent) / 2; |
| case AB_AFTER_EDGE: |
| case AB_TEXT_AFTER_EDGE: |
| case AB_IDEOGRAPHIC: |
| return -descent; |
| case AB_ALPHABETIC: |
| return 0; |
| case AB_HANGING: |
| return ascent * 8 / 10.f; |
| case AB_MATHEMATICAL: |
| return ascent / 2; |
| case AB_BASELINE: |
| default: |
| NOTREACHED(); |
| return 0; |
| } |
| } |
| |
| } // namespace blink |