/src/libreoffice/vcl/inc/impglyphitem.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <basegfx/range/b2drectangle.hxx> |
23 | | #include <o3tl/typed_flags_set.hxx> |
24 | | #include <vcl/dllapi.h> |
25 | | #include <vcl/rendercontext/SalLayoutFlags.hxx> |
26 | | #include <rtl/math.hxx> |
27 | | #include <vector> |
28 | | |
29 | | #include "font/LogicalFontInstance.hxx" |
30 | | #include "glyphid.hxx" |
31 | | |
32 | | enum class GlyphItemFlags : sal_uInt8 |
33 | | { |
34 | | NONE = 0, |
35 | | IS_IN_CLUSTER = 0x01, |
36 | | IS_RTL_GLYPH = 0x02, |
37 | | IS_VERTICAL = 0x04, |
38 | | IS_SPACING = 0x08, |
39 | | IS_DROPPED = 0x10, |
40 | | IS_CLUSTER_START = 0x20, |
41 | | IS_UNSAFE_TO_BREAK = 0x40, // HB_GLYPH_FLAG_UNSAFE_TO_BREAK from harfbuzz |
42 | | IS_SAFE_TO_INSERT_KASHIDA = 0x80 // HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL from harfbuzz |
43 | | }; |
44 | | namespace o3tl |
45 | | { |
46 | | template <> struct typed_flags<GlyphItemFlags> : is_typed_flags<GlyphItemFlags, 0xff> |
47 | | { |
48 | | }; |
49 | | }; |
50 | | |
51 | | class VCL_DLLPUBLIC GlyphItem |
52 | | { |
53 | | basegfx::B2DPoint m_aLinearPos; // absolute position of non rotated string |
54 | | double m_nOrigWidth; // original glyph width |
55 | | sal_Int32 m_nCharPos; // index in string (by grapheme cluster) |
56 | | sal_Int32 m_nOrigCharPos; // original index in string, if available |
57 | | double m_nXOffset; |
58 | | double m_nYOffset; |
59 | | double m_nNewWidth; // width after adjustments |
60 | | sal_GlyphId m_aGlyphId; |
61 | | GlyphItemFlags m_nFlags; |
62 | | sal_Int8 m_nCharCount; // number of characters making up this glyph |
63 | | |
64 | | public: |
65 | | GlyphItem(int nCharPos, int nCharCount, sal_GlyphId aGlyphId, |
66 | | const basegfx::B2DPoint& rLinearPos, GlyphItemFlags nFlags, double nOrigWidth, |
67 | | double nXOffset, double nYOffset, int nOrigCharPos) |
68 | 394M | : m_aLinearPos(rLinearPos) |
69 | 394M | , m_nOrigWidth(nOrigWidth) |
70 | 394M | , m_nCharPos(nCharPos) |
71 | 394M | , m_nOrigCharPos(nOrigCharPos) |
72 | 394M | , m_nXOffset(nXOffset) |
73 | 394M | , m_nYOffset(nYOffset) |
74 | 394M | , m_nNewWidth(nOrigWidth) |
75 | 394M | , m_aGlyphId(aGlyphId) |
76 | 394M | , m_nFlags(nFlags) |
77 | 394M | , m_nCharCount(nCharCount) |
78 | 394M | { |
79 | 394M | } |
80 | | |
81 | 26.7M | bool IsInCluster() const { return bool(m_nFlags & GlyphItemFlags::IS_IN_CLUSTER); } |
82 | 98.3M | bool IsRTLGlyph() const { return bool(m_nFlags & GlyphItemFlags::IS_RTL_GLYPH); } |
83 | 89.6M | bool IsVertical() const { return bool(m_nFlags & GlyphItemFlags::IS_VERTICAL); } |
84 | 34.2M | bool IsSpacing() const { return bool(m_nFlags & GlyphItemFlags::IS_SPACING); } |
85 | 0 | bool IsDropped() const { return bool(m_nFlags & GlyphItemFlags::IS_DROPPED); } |
86 | 11.3M | bool IsClusterStart() const { return bool(m_nFlags & GlyphItemFlags::IS_CLUSTER_START); } |
87 | 1.45M | bool IsUnsafeToBreak() const { return bool(m_nFlags & GlyphItemFlags::IS_UNSAFE_TO_BREAK); } |
88 | | bool IsSafeToInsertKashida() const |
89 | 0 | { |
90 | 0 | return bool(m_nFlags & GlyphItemFlags::IS_SAFE_TO_INSERT_KASHIDA); |
91 | 0 | } |
92 | | |
93 | | inline bool GetGlyphBoundRect(const LogicalFontInstance*, basegfx::B2DRectangle&) const; |
94 | | inline bool GetGlyphOutline(const LogicalFontInstance*, basegfx::B2DPolyPolygon&) const; |
95 | | inline void dropGlyph(); |
96 | | |
97 | 678M | sal_GlyphId glyphId() const { return m_aGlyphId; } |
98 | 816M | int charCount() const { return m_nCharCount; } |
99 | 3.21M | double origWidth() const { return m_nOrigWidth; } |
100 | 1.56G | int charPos() const { return m_nCharPos; } |
101 | 788M | int origCharPos() const { return m_nOrigCharPos; } |
102 | 983k | double xOffset() const { return m_nXOffset; } |
103 | 983k | double yOffset() const { return m_nYOffset; } |
104 | 1.31G | double newWidth() const { return m_nNewWidth; } |
105 | 153M | const basegfx::B2DPoint& linearPos() const { return m_aLinearPos; } |
106 | | |
107 | 1.47M | void setNewWidth(double width) { m_nNewWidth = width; } |
108 | 11.3M | void addNewWidth(double width) { m_nNewWidth += width; } |
109 | 55.4M | void setLinearPos(const basegfx::B2DPoint& point) { m_aLinearPos = point; } |
110 | 1.47M | void setLinearPosX(double x) { m_aLinearPos.setX(x); } |
111 | 11.3M | void adjustLinearPosX(double diff) { m_aLinearPos.adjustX(diff); } |
112 | | bool isLayoutEquivalent(const GlyphItem& other) const |
113 | 0 | { |
114 | 0 | return rtl::math::approxEqual(m_aLinearPos.getX(), other.m_aLinearPos.getX(), 8) |
115 | 0 | && rtl::math::approxEqual(m_aLinearPos.getY(), other.m_aLinearPos.getY(), 8) |
116 | 0 | && m_nOrigWidth == other.m_nOrigWidth && m_nCharPos == other.m_nCharPos |
117 | 0 | && m_nXOffset == other.m_nXOffset && m_nYOffset == other.m_nYOffset |
118 | 0 | && m_nNewWidth == other.m_nNewWidth && m_aGlyphId == other.m_aGlyphId |
119 | 0 | && m_nCharCount == other.m_nCharCount |
120 | 0 | && (m_nFlags & ~GlyphItemFlags::IS_UNSAFE_TO_BREAK) |
121 | 0 | == (other.m_nFlags & ~GlyphItemFlags::IS_UNSAFE_TO_BREAK); |
122 | 0 | } |
123 | | }; |
124 | | |
125 | | bool GlyphItem::GetGlyphBoundRect(const LogicalFontInstance* pFontInstance, |
126 | | basegfx::B2DRectangle& rRect) const |
127 | 56.9M | { |
128 | 56.9M | return pFontInstance->GetGlyphBoundRect(m_aGlyphId, rRect, IsVertical()); |
129 | 56.9M | } |
130 | | |
131 | | bool GlyphItem::GetGlyphOutline(const LogicalFontInstance* pFontInstance, |
132 | | basegfx::B2DPolyPolygon& rPoly) const |
133 | 479 | { |
134 | 479 | return pFontInstance->GetGlyphOutline(m_aGlyphId, rPoly, IsVertical()); |
135 | 479 | } |
136 | | |
137 | | void GlyphItem::dropGlyph() |
138 | 0 | { |
139 | 0 | m_nCharPos = -1; |
140 | 0 | m_nFlags |= GlyphItemFlags::IS_DROPPED; |
141 | 0 | } |
142 | | |
143 | | class SalLayoutGlyphsImpl : public std::vector<GlyphItem> |
144 | | { |
145 | | public: |
146 | | SalLayoutGlyphsImpl(LogicalFontInstance& rFontInstance) |
147 | 26.0M | : m_rFontInstance(&rFontInstance) |
148 | 26.0M | { |
149 | 26.0M | } |
150 | | SalLayoutGlyphsImpl* clone() const; |
151 | | SalLayoutGlyphsImpl* cloneCharRange(sal_Int32 index, sal_Int32 length) const; |
152 | 136M | const rtl::Reference<LogicalFontInstance>& GetFont() const { return m_rFontInstance; } |
153 | | bool IsValid() const; |
154 | 6.43M | void SetFlags(SalLayoutFlags flags) { mnFlags = flags; } |
155 | 13.9M | SalLayoutFlags GetFlags() const { return mnFlags; } |
156 | | #ifdef DBG_UTIL |
157 | | bool isLayoutEquivalent(const SalLayoutGlyphsImpl* other) const; |
158 | | #endif |
159 | | |
160 | | private: |
161 | | bool isSafeToBreak(const_iterator pos, bool rtl) const; |
162 | | rtl::Reference<LogicalFontInstance> m_rFontInstance; |
163 | | SalLayoutFlags mnFlags = SalLayoutFlags::NONE; |
164 | | }; |
165 | | |
166 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |