1 /**********************************************************************
2 * File: normalis.cpp (Formerly denorm.c)
3 * Description: Code for the DENORM class.
4 * Author: Ray Smith
5 * Created: Thu Apr 23 09:22:43 BST 1992
6 *
7 * (C) Copyright 1992, Hewlett-Packard Ltd.
8 ** Licensed under the Apache License, Version 2.0 (the "License");
9 ** you may not use this file except in compliance with the License.
10 ** You may obtain a copy of the License at
11 ** http://www.apache.org/licenses/LICENSE-2.0
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 *
18 **********************************************************************/
19
20 #include "mfcpch.h"
21 #include "werd.h"
22 #include "normalis.h"
23
24 /**********************************************************************
25 * DENORM::binary_search_segment
26 *
27 * Find the segment to use for the given x.
28 **********************************************************************/
29
binary_search_segment(float src_x) const30 const DENORM_SEG *DENORM::binary_search_segment(float src_x) const {
31 int bottom, top, middle; //binary search
32
33 bottom = 0;
34 top = segments;
35 do {
36 middle = (bottom + top) / 2;
37 if (segs[middle].xstart > src_x)
38 top = middle;
39 else
40 bottom = middle;
41 }
42 while (top - bottom > 1);
43 return &segs[bottom];
44 }
45
46 /**********************************************************************
47 * DENORM::scale_at_x
48 *
49 * Return scaling at a given (normalized) x coord.
50 **********************************************************************/
51
scale_at_x(float src_x) const52 float DENORM::scale_at_x(float src_x) const { // In normalized coords.
53 if (segments != 0) {
54 const DENORM_SEG* seg = binary_search_segment(src_x);
55 if (seg->scale_factor > 0.0)
56 return seg->scale_factor;
57 }
58 return scale_factor;
59 }
60
61 /**********************************************************************
62 * DENORM::yshift_at_x
63 *
64 * Return yshift at a given (normalized) x coord.
65 **********************************************************************/
66
yshift_at_x(float src_x) const67 float DENORM::yshift_at_x(float src_x) const { // In normalized coords.
68 if (segments != 0) {
69 const DENORM_SEG* seg = binary_search_segment(src_x);
70 if (seg->ycoord == -MAX_INT32) {
71 if (base_is_row)
72 return source_row->base_line(x(src_x)/scale_at_x(src_x) + x_centre);
73 else
74 return m * x(src_x) + c;
75 } else {
76 return seg->ycoord;
77 }
78 }
79 return source_row->base_line (x(src_x)/scale_at_x(src_x) + x_centre);
80 }
81
82 /**********************************************************************
83 * DENORM::x
84 *
85 * Denormalise an x coordinate.
86 **********************************************************************/
87
x(float src_x) const88 float DENORM::x( //convert x coord
89 float src_x //coord to convert
90 ) const {
91 return src_x / scale_at_x(src_x) + x_centre;
92 }
93
94
95 /**********************************************************************
96 * DENORM::y
97 *
98 * Denormalise a y coordinate.
99 **********************************************************************/
100
y(float src_y,float src_centre) const101 float DENORM::y( //convert y coord
102 float src_y, //coord to convert
103 float src_centre //x location for base
104 ) const {
105 return (src_y - bln_baseline_offset) / scale_at_x(src_centre)
106 + yshift_at_x(src_centre);
107 }
108
109
DENORM(float x,float scaling,double line_m,double line_c,inT16 seg_count,DENORM_SEG * seg_pts,BOOL8 using_row,ROW * src)110 DENORM::DENORM(float x, //from same pieces
111 float scaling,
112 double line_m, //default line
113 double line_c,
114 inT16 seg_count, //no of segments
115 DENORM_SEG *seg_pts, //actual segments
116 BOOL8 using_row, //as baseline
117 ROW *src) {
118 x_centre = x; //just copy
119 scale_factor = scaling;
120 source_row = src;
121 if (seg_count > 0) {
122 segs = new DENORM_SEG[seg_count];
123 for (segments = 0; segments < seg_count; segments++) {
124 // It is possible, if infrequent that the segments may be out of order.
125 // since we are searching with a binary search, keep them in order.
126 if (segments == 0 || segs[segments - 1].xstart <=
127 seg_pts[segments].xstart) {
128 segs[segments] = seg_pts[segments];
129 } else {
130 int i;
131 for (i = 0; i < segments
132 && segs[segments - 1 - i].xstart > seg_pts[segments].xstart;
133 ++i) {
134 segs[segments - i ] = segs[segments - 1 - i];
135 }
136 segs[segments - i] = seg_pts[segments];
137 }
138 }
139 }
140 else {
141 segments = 0;
142 segs = NULL;
143 }
144 base_is_row = using_row;
145 m = line_m;
146 c = line_c;
147 block_ = NULL;
148 }
149
150
DENORM(const DENORM & src)151 DENORM::DENORM(const DENORM &src) {
152 segments = 0;
153 segs = NULL;
154 *this = src;
155 }
156
157
operator =(const DENORM & src)158 DENORM & DENORM::operator= (const DENORM & src) {
159 x_centre = src.x_centre;
160 scale_factor = src.scale_factor;
161 source_row = src.source_row;
162 if (segments > 0)
163 delete[]segs;
164 if (src.segments > 0) {
165 segs = new DENORM_SEG[src.segments];
166 for (segments = 0; segments < src.segments; segments++)
167 segs[segments] = src.segs[segments];
168 }
169 else {
170 segments = 0;
171 segs = NULL;
172 }
173 base_is_row = src.base_is_row;
174 m = src.m;
175 c = src.c;
176 block_ = src.block_;
177 return *this;
178 }
179