LibreOffice Module vcl (master) 1
EmphasisMark.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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
10#include <sal/config.h>
11
12#include <font/EmphasisMark.hxx>
13
14namespace vcl::font
15{
16EmphasisMark::EmphasisMark(FontEmphasisMark eEmphasis, tools::Long nHeight, sal_Int32 nDPIY)
17{
18 static const PolyFlags aAccentPolyFlags[24] =
19 {
20 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
21 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
22 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
23 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
24 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
25 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
26 PolyFlags::Normal, PolyFlags::Normal, PolyFlags::Control,
27 PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control
28 };
29
30 static const Point aAccentPos[24] =
31 {
32 { 78, 0 },
33 { 348, 79 },
34 { 599, 235 },
35 { 843, 469 },
36 { 938, 574 },
37 { 990, 669 },
38 { 990, 773 },
39 { 990, 843 },
40 { 964, 895 },
41 { 921, 947 },
42 { 886, 982 },
43 { 860, 999 },
44 { 825, 999 },
45 { 764, 999 },
46 { 721, 964 },
47 { 686, 895 },
48 { 625, 791 },
49 { 556, 660 },
50 { 469, 504 },
51 { 400, 400 },
52 { 261, 252 },
53 { 61, 61 },
54 { 0, 27 },
55 { 9, 0 }
56 };
57
58 mnWidth = 0;
59 mnYOff = 0;
60 mbIsPolyLine = false;
61
62 if ( !nHeight )
63 return;
64
65 FontEmphasisMark nEmphasisStyle = eEmphasis & FontEmphasisMark::Style;
66 tools::Long nDotSize = 0;
67 switch ( nEmphasisStyle )
68 {
69 case FontEmphasisMark::Dot:
70 // Dot has 55% of the height
71 nDotSize = (nHeight*550)/1000;
72 if ( !nDotSize )
73 nDotSize = 1;
74 if ( nDotSize <= 2 )
75 maRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
76 else
77 {
78 tools::Long nRad = nDotSize/2;
79 tools::Polygon aPoly( Point( nRad, nRad ), nRad, nRad );
80 maPolyPoly.Insert( aPoly );
81 }
82 mnYOff = ((nHeight*250)/1000)/2; // Center to the another EmphasisMarks
83 mnWidth = nDotSize;
84 break;
85
86 case FontEmphasisMark::Circle:
87 // Dot has 80% of the height
88 nDotSize = (nHeight*800)/1000;
89 if ( !nDotSize )
90 nDotSize = 1;
91 if ( nDotSize <= 2 )
92 maRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
93 else
94 {
95 tools::Long nRad = nDotSize/2;
96 tools::Polygon aPoly( Point( nRad, nRad ), nRad, nRad );
97 maPolyPoly.Insert( aPoly );
98 // Border mnWidth is 15%
99 tools::Long nBorder = (nDotSize*150)/1000;
100 if ( nBorder <= 1 )
101 mbIsPolyLine = true;
102 else
103 {
104 tools::Polygon aPoly2( Point( nRad, nRad ),
105 nRad-nBorder, nRad-nBorder );
106 maPolyPoly.Insert( aPoly2 );
107 }
108 }
109 mnWidth = nDotSize;
110 break;
111
112 case FontEmphasisMark::Disc:
113 // Dot has 80% of the height
114 nDotSize = (nHeight*800)/1000;
115 if ( !nDotSize )
116 nDotSize = 1;
117 if ( nDotSize <= 2 )
118 maRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
119 else
120 {
121 tools::Long nRad = nDotSize/2;
122 tools::Polygon aPoly( Point( nRad, nRad ), nRad, nRad );
123 maPolyPoly.Insert( aPoly );
124 }
125 mnWidth = nDotSize;
126 break;
127
128 case FontEmphasisMark::Accent:
129 // Dot has 80% of the height
130 nDotSize = (nHeight*800)/1000;
131 if ( !nDotSize )
132 nDotSize = 1;
133 if ( nDotSize <= 2 )
134 {
135 if ( nDotSize == 1 )
136 {
137 maRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
138 mnWidth = nDotSize;
139 }
140 else
141 {
142 maRect1 = tools::Rectangle( Point(), Size( 1, 1 ) );
143 maRect2 = tools::Rectangle( Point( 1, 1 ), Size( 1, 1 ) );
144 }
145 }
146 else
147 {
148 tools::Polygon aPoly( SAL_N_ELEMENTS(aAccentPos), aAccentPos,
149 aAccentPolyFlags );
150 double dScale = static_cast<double>(nDotSize)/1000.0;
151 aPoly.Scale( dScale, dScale );
152 tools::Polygon aTemp;
153 aPoly.AdaptiveSubdivide( aTemp );
154 tools::Rectangle aBoundRect = aTemp.GetBoundRect();
155 mnWidth = aBoundRect.GetWidth();
156 nDotSize = aBoundRect.GetHeight();
157 maPolyPoly.Insert( aTemp );
158 }
159 break;
160 default: break;
161 }
162
163 // calculate position
164 tools::Long nOffY = 1+(nDPIY/300); // one visible pixel space
165 tools::Long nSpaceY = nHeight-nDotSize;
166 if ( nSpaceY >= nOffY*2 )
167 mnYOff += nOffY;
168
169 if ( !(eEmphasis & FontEmphasisMark::PosBelow) )
170 mnYOff += nDotSize;
171}
172}
173
174/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
tools::Rectangle GetBoundRect() const
void Scale(double fScaleX, double fScaleY)
void AdaptiveSubdivide(tools::Polygon &rResult, const double d=1.0) const
constexpr tools::Long GetWidth() const
constexpr tools::Long GetHeight() const
EmphasisMark(FontEmphasisMark eEmphasis, tools::Long nHeight, sal_Int32 nDPIY)
tools::Rectangle maRect2
tools::PolyPolygon maPolyPoly
tools::Rectangle maRect1
FontEmphasisMark
#define SAL_N_ELEMENTS(arr)
tools::Long const nBorder
long Long
A PhysicalFontFaceCollection is created by a PhysicalFontCollection and becomes invalid when original...
PolyFlags