/********************************************************************** * File: normalis.cpp (Formerly denorm.c) * Description: Code for the DENORM class. * Author: Ray Smith * Created: Thu Apr 23 09:22:43 BST 1992 * * (C) Copyright 1992, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/ #include "mfcpch.h" #include "werd.h" #include "normalis.h" /********************************************************************** * DENORM::binary_search_segment * * Find the segment to use for the given x. **********************************************************************/ const DENORM_SEG *DENORM::binary_search_segment(float src_x) const { int bottom, top, middle; //binary search bottom = 0; top = segments; do { middle = (bottom + top) / 2; if (segs[middle].xstart > src_x) top = middle; else bottom = middle; } while (top - bottom > 1); return &segs[bottom]; } /********************************************************************** * DENORM::scale_at_x * * Return scaling at a given (normalized) x coord. **********************************************************************/ float DENORM::scale_at_x(float src_x) const { // In normalized coords. if (segments != 0) { const DENORM_SEG* seg = binary_search_segment(src_x); if (seg->scale_factor > 0.0) return seg->scale_factor; } return scale_factor; } /********************************************************************** * DENORM::yshift_at_x * * Return yshift at a given (normalized) x coord. **********************************************************************/ float DENORM::yshift_at_x(float src_x) const { // In normalized coords. if (segments != 0) { const DENORM_SEG* seg = binary_search_segment(src_x); if (seg->ycoord == -MAX_INT32) { if (base_is_row) return source_row->base_line(x(src_x)/scale_at_x(src_x) + x_centre); else return m * x(src_x) + c; } else { return seg->ycoord; } } return source_row->base_line (x(src_x)/scale_at_x(src_x) + x_centre); } /********************************************************************** * DENORM::x * * Denormalise an x coordinate. **********************************************************************/ float DENORM::x( //convert x coord float src_x //coord to convert ) const { return src_x / scale_at_x(src_x) + x_centre; } /********************************************************************** * DENORM::y * * Denormalise a y coordinate. **********************************************************************/ float DENORM::y( //convert y coord float src_y, //coord to convert float src_centre //x location for base ) const { return (src_y - bln_baseline_offset) / scale_at_x(src_centre) + yshift_at_x(src_centre); } DENORM::DENORM(float x, //from same pieces float scaling, double line_m, //default line double line_c, inT16 seg_count, //no of segments DENORM_SEG *seg_pts, //actual segments BOOL8 using_row, //as baseline ROW *src) { x_centre = x; //just copy scale_factor = scaling; source_row = src; if (seg_count > 0) { segs = new DENORM_SEG[seg_count]; for (segments = 0; segments < seg_count; segments++) { // It is possible, if infrequent that the segments may be out of order. // since we are searching with a binary search, keep them in order. if (segments == 0 || segs[segments - 1].xstart <= seg_pts[segments].xstart) { segs[segments] = seg_pts[segments]; } else { int i; for (i = 0; i < segments && segs[segments - 1 - i].xstart > seg_pts[segments].xstart; ++i) { segs[segments - i ] = segs[segments - 1 - i]; } segs[segments - i] = seg_pts[segments]; } } } else { segments = 0; segs = NULL; } base_is_row = using_row; m = line_m; c = line_c; } DENORM::DENORM(const DENORM &src) { segments = 0; segs = NULL; *this = src; } DENORM & DENORM::operator= (const DENORM & src) { x_centre = src.x_centre; scale_factor = src.scale_factor; source_row = src.source_row; if (segments > 0) delete[]segs; if (src.segments > 0) { segs = new DENORM_SEG[src.segments]; for (segments = 0; segments < src.segments; segments++) segs[segments] = src.segs[segments]; } else { segments = 0; segs = NULL; } base_is_row = src.base_is_row; m = src.m; c = src.c; return *this; }