/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_CONCAT = 0x40, // HB_GLYPH_FLAG_UNSAFE_TO_CONCAT 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 | 227M | : m_aLinearPos(rLinearPos) |
69 | 227M | , m_nOrigWidth(nOrigWidth) |
70 | 227M | , m_nCharPos(nCharPos) |
71 | 227M | , m_nOrigCharPos(nOrigCharPos) |
72 | 227M | , m_nXOffset(nXOffset) |
73 | 227M | , m_nYOffset(nYOffset) |
74 | 227M | , m_nNewWidth(nOrigWidth) |
75 | 227M | , m_aGlyphId(aGlyphId) |
76 | 227M | , m_nFlags(nFlags) |
77 | 227M | , m_nCharCount(nCharCount) |
78 | 227M | { |
79 | 227M | } |
80 | | |
81 | 22.8M | bool IsInCluster() const { return bool(m_nFlags & GlyphItemFlags::IS_IN_CLUSTER); } |
82 | 41.0M | bool IsRTLGlyph() const { return bool(m_nFlags & GlyphItemFlags::IS_RTL_GLYPH); } |
83 | 59.9M | bool IsVertical() const { return bool(m_nFlags & GlyphItemFlags::IS_VERTICAL); } |
84 | 16.3M | bool IsSpacing() const { return bool(m_nFlags & GlyphItemFlags::IS_SPACING); } |
85 | 0 | bool IsDropped() const { return bool(m_nFlags & GlyphItemFlags::IS_DROPPED); } |
86 | 10.0M | bool IsClusterStart() const { return bool(m_nFlags & GlyphItemFlags::IS_CLUSTER_START); } |
87 | 1.16M | bool IsUnsafeToConcat() const { return bool(m_nFlags & GlyphItemFlags::IS_UNSAFE_TO_CONCAT); } |
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 | 331M | sal_GlyphId glyphId() const { return m_aGlyphId; } |
98 | 378M | int charCount() const { return m_nCharCount; } |
99 | 1.74M | double origWidth() const { return m_nOrigWidth; } |
100 | 787M | int charPos() const { return m_nCharPos; } |
101 | 455M | int origCharPos() const { return m_nOrigCharPos; } |
102 | 477k | double xOffset() const { return m_nXOffset; } |
103 | 477k | double yOffset() const { return m_nYOffset; } |
104 | 633M | double newWidth() const { return m_nNewWidth; } |
105 | 72.2M | const basegfx::B2DPoint& linearPos() const { return m_aLinearPos; } |
106 | | |
107 | 659k | void setNewWidth(double width) { m_nNewWidth = width; } |
108 | 10.1M | void addNewWidth(double width) { m_nNewWidth += width; } |
109 | 8.44M | void setLinearPos(const basegfx::B2DPoint& point) { m_aLinearPos = point; } |
110 | 659k | void setLinearPosX(double x) { m_aLinearPos.setX(x); } |
111 | 10.1M | 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_CONCAT) |
121 | 0 | == (other.m_nFlags & ~GlyphItemFlags::IS_UNSAFE_TO_CONCAT); |
122 | 0 | } |
123 | | }; |
124 | | |
125 | | bool GlyphItem::GetGlyphBoundRect(const LogicalFontInstance* pFontInstance, |
126 | | basegfx::B2DRectangle& rRect) const |
127 | 39.4M | { |
128 | 39.4M | return pFontInstance->GetGlyphBoundRect(m_aGlyphId, rRect, IsVertical()); |
129 | 39.4M | } |
130 | | |
131 | | bool GlyphItem::GetGlyphOutline(const LogicalFontInstance* pFontInstance, |
132 | | basegfx::B2DPolyPolygon& rPoly) const |
133 | 492 | { |
134 | 492 | return pFontInstance->GetGlyphOutline(m_aGlyphId, rPoly, IsVertical()); |
135 | 492 | } |
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 | 15.2M | : m_rFontInstance(&rFontInstance) |
148 | 15.2M | { |
149 | 15.2M | } |
150 | | SalLayoutGlyphsImpl* clone() const; |
151 | | SalLayoutGlyphsImpl* cloneCharRange(sal_Int32 index, sal_Int32 length) const; |
152 | 80.3M | const rtl::Reference<LogicalFontInstance>& GetFont() const { return m_rFontInstance; } |
153 | | bool IsValid() const; |
154 | 5.06M | void SetFlags(SalLayoutFlags flags) { mnFlags = flags; } |
155 | 10.7M | 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: */ |