~ubuntu-branches/ubuntu/quantal/texmacs/quantal

« back to all changes in this revision

Viewing changes to src/Graphics/Bitmap_fonts/glyph_shrink.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Atsuhito KOHDA, Kamaraju Kusumanchi, kohda
  • Date: 2008-04-06 15:11:41 UTC
  • mfrom: (1.1.7 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080406151141-w0sg20jnv86mlt6f
Tags: 1:1.0.6.14-1
[Kamaraju Kusumanchi <kamaraju@gmail.com>]
* New upstream release
* 01_american.dpatch is updated
* Since thread support in guile-1.8 is now disabled, the segmentation faults
  should not arise anymore. More info at #439923. (Closes: #450499, #458685)
[kohda]
* This version fixed menu problem.  (Closes: #447083)
* Reverted orig.tar.gz to the upstream tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/******************************************************************************
 
3
* MODULE     : glyph_shrink.cpp
 
4
* DESCRIPTION: shrinking glyphs for anti-aliasing
 
5
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
 
6
*******************************************************************************
 
7
* This software falls under the GNU general public license and comes WITHOUT
 
8
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
 
9
* If you don't have this file, write to the Free Software Foundation, Inc.,
 
10
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
11
******************************************************************************/
 
12
 
 
13
#include "bitmap_font.hpp"
 
14
#include "renderer.hpp"
 
15
 
 
16
static int
 
17
log2i (int i) {
 
18
  int l;
 
19
  if (i==1) return 0;
 
20
  for (l=1; l<30; l++)
 
21
    if (i <= (1 << l)) return l;
 
22
  fatal_error ("too large shrinking factor", "shrink", "shrink.cpp");
 
23
  return 0; // Because of bug in certain versions of g++
 
24
}
 
25
 
 
26
static int
 
27
my_div (int a, int b) {
 
28
  if (a>=0) return a/b;
 
29
  else return -((b-1-a)/b);
 
30
}
 
31
 
 
32
static int
 
33
my_mod (int a, int b) {
 
34
  if (a>=0) return a%b;
 
35
  else return b-1-((-1-a)%b);
 
36
}
 
37
 
 
38
static int
 
39
my_norm (int a, int m) {
 
40
  a= my_mod (a, m);
 
41
  if (a<=(m>>1)) return a;
 
42
  else return m-a;
 
43
}
 
44
 
 
45
int
 
46
get_hor_shift (glyph gl, int xfactor, int tx) {
 
47
  STACK_NEW_ARRAY (flag, bool, gl->width);
 
48
 
 
49
  // cout << "[";
 
50
  int x;
 
51
  for (x=0; x<gl->width; x++) {
 
52
    int max_count= 0, count=0, y;
 
53
    for (y=0; y<gl->height; y++)
 
54
      if (gl->get_1 (x,y)) count++;
 
55
      else {
 
56
        max_count = max (max_count, count);
 
57
        count     = 0;
 
58
      }
 
59
    max_count= max (max_count, count);
 
60
    flag[x]= (max_count>(gl->height>>1));
 
61
    // if (flag[x]) cout << "*"; else cout << " ";
 
62
  }
 
63
  // cout << "]   ";
 
64
 
 
65
  int first0=-1, first1=-1, last0=-1, last1=-1;
 
66
  for (x=0; x<gl->width; x++)
 
67
    if (flag[x]) {
 
68
      if (first0<0) first0= x;
 
69
      last0= x;
 
70
      while ((x<gl->width) && flag[x]) x++;
 
71
      if (first1<0) first1= x+ tx;
 
72
      last1= x+ tx;
 
73
      x--;
 
74
    }
 
75
  /* cout << first0 << ", " << first1 << ", "
 
76
     << last0  << ", " << last1  << "\n"; */
 
77
 
 
78
  STACK_DELETE_ARRAY (flag);
 
79
 
 
80
  if (first0==-1) return 0;
 
81
  if (first0==last0) return my_mod (gl->xoff- first0, xfactor);
 
82
 
 
83
  int first, last;
 
84
  int d00= my_norm (last0- first0, xfactor);
 
85
  int d01= my_norm (last1- first0, xfactor);
 
86
  int d10= my_norm (last0- first1, xfactor);
 
87
  int d11= my_norm (last1- first1, xfactor);
 
88
  if ((d00<=d01) && (d00<=d10) && (d00<=d11)) { first= first0; last= last0; }
 
89
  else if ((d01<=d10) && (d01<=d11)) { first= first0; last= last1; }
 
90
  else if (d10<=d11) { first= first1; last= last0; }
 
91
  else { first= first1; last= last1; }
 
92
 
 
93
  int middle, rest= my_mod (last- first, xfactor);
 
94
  if (rest <= (xfactor>>1)) middle= first+ (rest>>1);
 
95
  else middle= first- ((xfactor-rest)>>1);
 
96
  return my_mod (gl->xoff- middle, xfactor);
 
97
}
 
98
 
 
99
int
 
100
get_ver_shift (glyph gl, int yfactor, int ty) {
 
101
  STACK_NEW_ARRAY (flag, bool, gl->height);
 
102
 
 
103
  // cout << "[";
 
104
  int y;
 
105
  for (y=0; y<gl->height; y++) {
 
106
    int max_count= 0, count=0, x;
 
107
    for (x=0; x<gl->width; x++)
 
108
      if (gl->get_1 (x,y)) count++;
 
109
      else {
 
110
        max_count = max (max_count, count);
 
111
        count     = 0;
 
112
      }
 
113
    max_count= max (max_count, count);
 
114
    flag[y]= (max_count>(gl->width>>1));
 
115
    // if (flag[y]) cout << "*"; else cout << " ";
 
116
  }
 
117
  // cout << "]   ";
 
118
 
 
119
  int first0=-1, first1=-1, last0=-1, last1=-1;
 
120
  for (y=0; y<gl->height; y++)
 
121
    if (flag[y]) {
 
122
      if (first0<0) first0= y;
 
123
      last0= y;
 
124
      while ((y<gl->height) && flag[y]) y++;
 
125
      if (first1<0) first1= y+ ty;
 
126
      last1= y+ ty;
 
127
      y--;
 
128
    }
 
129
  /* cout << first0 << ", " << first1 << ", "
 
130
     << last0  << ", " << last1  << "\n"; */
 
131
 
 
132
  STACK_DELETE_ARRAY (flag);
 
133
 
 
134
  if (first0==-1) return 0;
 
135
  if (first0==last0)
 
136
    return my_mod (gl->height- gl->yoff- 1- first0, yfactor);
 
137
 
 
138
  int first, last;
 
139
  int d00= my_norm (last0- first0, yfactor);
 
140
  int d01= my_norm (last1- first0, yfactor);
 
141
  int d10= my_norm (last0- first1, yfactor);
 
142
  int d11= my_norm (last1- first1, yfactor);
 
143
  if ((d00<=d01) && (d00<=d10) && (d00<=d11)) { first= first0; last= last0; }
 
144
  else if ((d01<=d10) && (d01<=d11)) { first= first0; last= last1; }
 
145
  else if (d10<=d11) { first= first1; last= last0; }
 
146
  else { first= first1; last= last1; }
 
147
 
 
148
  int middle, rest= my_mod (last- first, yfactor);
 
149
  if (rest <= (yfactor>>1)) middle= first+ (rest>>1);
 
150
  else middle= first- ((yfactor-rest)>>1);
 
151
  return my_mod (gl->height- gl->yoff- 1- middle, yfactor);
 
152
}
 
153
 
 
154
glyph
 
155
shrink (glyph gl, int xfactor, int yfactor,
 
156
        int dx, int dy, int tx, int ty, SI& xo, SI& yo)
 
157
{
 
158
  /*
 
159
  cout << "------------------------------------------------------------------------------\n";
 
160
  cout << "Shift by " << dx << ", " << dy << "\n";
 
161
  cout << "------------------------------------------------------------------------------\n\n";
 
162
  cout << gl << "\n";
 
163
  */
 
164
 
 
165
  int x1= dx- gl->xoff;
 
166
  int x2= dx- gl->xoff+ gl->width+ tx;
 
167
  int X1= my_div (x1, xfactor);
 
168
  int X2= my_div (x2+xfactor-1, xfactor);
 
169
 
 
170
  int y1= dy+ gl->yoff+ 1- gl->height;
 
171
  int y2= dy+ gl->yoff+ 1+ ty;
 
172
  int Y1= my_div (y1, yfactor);
 
173
  int Y2= my_div (y2+yfactor-1, yfactor);
 
174
 
 
175
  int frac_x= (dx- gl->xoff- X1*xfactor);
 
176
  int frac_y= (dy+ gl->yoff- Y1*yfactor);
 
177
  SI  off_x = (((-X1) *xfactor+ dx)*PIXEL + ((tx*PIXEL)>>1))/xfactor;
 
178
  SI  off_y = (((Y2-1)*yfactor- dy)*PIXEL - ((ty*PIXEL)>>1))/yfactor;
 
179
 
 
180
  int i, j, x, y;
 
181
  int index, indey, entry;
 
182
  int ww=(X2-X1)*xfactor, hh=(Y2-Y1)*yfactor;
 
183
  STACK_NEW_ARRAY (bitmap, int, ww*hh);
 
184
  for (i=0; i<ww*hh; i++) bitmap[i]=0;
 
185
  for (y=0, index= ww*frac_y+ frac_x; y<gl->height; y++, index-=ww)
 
186
    for (x=0; x<gl->width; x++)
 
187
      if (gl->get_1(x,y))
 
188
        for (j=0, indey=ww*ty; j<=ty; j++, indey-=ww) {
 
189
          entry = index+indey+x;
 
190
          for (i=0; i<=tx; i++, entry++)
 
191
            bitmap[entry]= 1;
 
192
        }
 
193
 
 
194
  int X, Y, sum, nr= xfactor*yfactor;
 
195
  int new_depth= gl->depth+ log2i (nr);
 
196
  if (new_depth > 8) new_depth= 8;
 
197
  glyph CB (X2-X1, Y2-Y1, -X1, Y2-1, new_depth, gl->status);
 
198
  for (Y=Y1; Y<Y2; Y++)
 
199
    for (X=X1; X<X2; X++) {
 
200
      sum=0;
 
201
      indey= ((Y-Y1)*ww+ (X-X1))*xfactor;
 
202
      for (j=0, index= indey; j<yfactor; j++, index+=ww)
 
203
        for (i=0; i<xfactor; i++)
 
204
          sum += bitmap[index+ i];
 
205
      if (nr >= 64) sum= (64 * sum) / nr;
 
206
      CB->set (X, Y, sum);
 
207
    }
 
208
  xo= off_x;
 
209
  yo= off_y;
 
210
  STACK_DELETE_ARRAY (bitmap);
 
211
 
 
212
  // cout << CB << "\n";
 
213
  return CB;
 
214
}
 
215
 
 
216
glyph
 
217
shrink (glyph gl, int xfactor, int yfactor, SI& xo, SI& yo) {
 
218
  if ((gl->width==0) || (gl->height==0))
 
219
    fatal_error ("zero size character", "shrink", "glyph.cpp");
 
220
 
 
221
  int tx= xfactor/3;
 
222
  int ty= yfactor/3;
 
223
  int dx=0, dy=0;
 
224
  if ((gl->status==0) && (xfactor>1)) dx= get_hor_shift (gl, xfactor, tx);
 
225
  // if ((gl->status==0) && (yfactor>1)) dy= get_ver_shift (gl, yfactor, ty);
 
226
 
 
227
  glyph ret= shrink (gl, xfactor, yfactor, dx, dy, tx, ty, xo, yo);
 
228
  if (ret->status != 0) {
 
229
    if (ret->status&1) ret->adjust_top ();
 
230
    if (ret->status&2) ret->adjust_bot ();
 
231
    ret->yoff= yo= 0;
 
232
  }
 
233
  return ret;
 
234
}