"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/Graphics/Bitmap_fonts/glyph_ops.cpp" between
TeXmacs-1.99.4-src.tar.gz and TeXmacs-1.99.5-src.tar.gz

About: GNU TeXmacs is a what-you-see-is-what-you-get scientific text editor, which was both inspired by TeX and GNU Emacs.

glyph_ops.cpp  (TeXmacs-1.99.4-src):glyph_ops.cpp  (TeXmacs-1.99.5-src)
skipping to change at line 15 skipping to change at line 15
* COPYRIGHT : (C) 1999 Joris van der Hoeven * COPYRIGHT : (C) 1999 Joris van der Hoeven
******************************************************************************* *******************************************************************************
* This software falls under the GNU general public license version 3 or later. * This software falls under the GNU general public license version 3 or later.
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
******************************************************************************/ ******************************************************************************/
#include "bitmap_font.hpp" #include "bitmap_font.hpp"
#include "renderer.hpp" #include "renderer.hpp"
/******************************************************************************
* Information about glyphs
******************************************************************************/
void
get_bounding_box (glyph gl, SI& x1, SI& y1, SI& x2, SI& y2) {
x1= (-gl->xoff) * PIXEL;
x2= (gl->width - gl->xoff) * PIXEL;
y1= (gl->yoff - gl->height) * PIXEL;
y2= (gl->yoff) * PIXEL;
}
bool
empty_column (glyph gl, int i) {
int hh= gl->height;
for (int j=0; j<hh; j++)
if (gl->get_x (i, j) != 0)
return false;
return true;
}
bool
empty_row (glyph gl, int j) {
int ww= gl->width;
for (int i=0; i<ww; i++)
if (gl->get_x (i, j) != 0)
return false;
return true;
}
int
first_in_row (glyph gl, int j) {
int ww= gl->width;
for (int i=0; i<ww; i++)
if (gl->get_x (i, j) != 0)
return i;
return ww;
}
int
first_in_rows (glyph gl, int j1, int j2) {
int i= gl->width;
for (int j=j1; j<=j2; j++)
i= min (i, first_in_row (gl, j));
return i;
}
int
last_in_row (glyph gl, int j) {
int ww= gl->width;
for (int i=ww-1; i>=0; i--)
if (gl->get_x (i, j) != 0)
return i;
return -1;
}
int
last_in_rows (glyph gl, int j1, int j2) {
int i= -1;
for (int j=j1; j<=j2; j++)
i= max (i, last_in_row (gl, j));
return i;
}
int
first_in_column (glyph gl, int i) {
int hh= gl->height;
for (int j=0; j<hh; j++)
if (gl->get_x (i, j) != 0)
return j;
return hh;
}
int
last_in_column (glyph gl, int i) {
int hh= gl->height;
for (int j=hh-1; j>=0; j--)
if (gl->get_x (i, j) != 0)
return j;
return -1;
}
SI
collision_offset (glyph gl1, glyph gl2, bool overlap) {
int w1= gl1->width, h1= gl1->height, h2= gl2->height;
int best= -1000000;
for (int j2=0; j2<h2; j2++) {
int y = gl2->yoff - j2;
int j1= gl1->yoff - y;
if (0 <= j1 && j1 < h1 &&
!empty_row (gl1, j1) &&
!empty_row (gl2, j2)) {
int end1 = last_in_row (gl1, j1);
int start2= first_in_row (gl2, j2);
int end2 = last_in_row (gl2, j2);
int di = end1 - (overlap? end2: start2);
int dx = di - gl1->xoff + gl2->xoff;
best= max (best, dx);
}
}
if (best > -1000000) return best * PIXEL;
return (gl1->xoff + w1 - gl2->xoff) * PIXEL;
}
int
probe (glyph gl, int x, int y, int dx, int dy) {
// Find distance to first pixel from a given point into a given direction
int w= gl->width, h= gl->height;
int i0= gl->xoff + x;
int j0= gl->yoff - y;
int i= i0, j= j0, di= dx, dj= -dy;
if (i < 0 && di > 0) i= 0;
if (i >= w && di < 0) i= w-1;
if (j < 0 && dj > 0) j= 0;
if (j >= h && dj < 0) j= h-1;
while (true) {
if (0 > i || i >= w || 0 > j || j >= h) return 0;
if (gl->get_x (i, j) != 0) break;
i += di; j += dj;
}
if (di != 0) return i - i0;
if (dj != 0) return j0 - j;
return 0;
}
/******************************************************************************
* Combining glyphs
******************************************************************************/
glyph glyph
join (glyph gl1, glyph gl2) { join (glyph gl1, glyph gl2) {
int x1= min (-gl1->xoff, -gl2->xoff); int x1= min (-gl1->xoff, -gl2->xoff);
int y1= min (gl1->yoff- gl1->height, gl2->yoff- gl2->height); int y1= min (gl1->yoff- gl1->height, gl2->yoff- gl2->height);
int x2= max (gl1->width- gl1->xoff, gl2->width- gl2->xoff); int x2= max (gl1->width- gl1->xoff, gl2->width- gl2->xoff);
int y2= max (gl1->yoff, gl2->yoff); int y2= max (gl1->yoff, gl2->yoff);
glyph bmr (x2-x1, y2-y1, -x1, y2, max (gl1->depth, gl2->depth)); glyph bmr (x2-x1, y2-y1, -x1, y2, max (gl1->depth, gl2->depth));
int i, j, dx, dy; int i, j, dx, dy;
dx= -gl1->xoff- x1, dy= y2- gl1->yoff; dx= -gl1->xoff- x1, dy= y2- gl1->yoff;
for (j=0; j<gl1->height; j++) for (j=0; j<gl1->height; j++)
for (i=0; i<gl1->width; i++) for (i=0; i<gl1->width; i++)
bmr->set_x (i+dx, j+dy, gl1->get_x (i, j)); bmr->set_x (i+dx, j+dy, gl1->get_x (i, j));
dx= -gl2->xoff- x1; dy= y2- gl2->yoff; dx= -gl2->xoff- x1; dy= y2- gl2->yoff;
for (j=0; j<gl2->height; j++) for (j=0; j<gl2->height; j++)
for (i=0; i<gl2->width; i++) for (i=0; i<gl2->width; i++)
bmr->set_x (i+dx, j+dy, bmr->set_x (i+dx, j+dy,
max (bmr->get_x (i+dx, j+dy), gl2->get_x (i, j))); max (bmr->get_x (i+dx, j+dy), gl2->get_x (i, j)));
int lo= min (-gl1->xoff, -gl2->xoff);
int hi= max (gl1->lwidth - gl1->xoff, gl2->lwidth - gl2->xoff);
bmr->lwidth= hi - lo;
return bmr;
}
glyph
intersect (glyph gl1, glyph gl2) {
int i, j;
int ww= gl1->width, hh= gl1->height, ww2= gl2->width, hh2= gl2->height;
glyph bmr (ww, hh, gl1->xoff, gl1->yoff, gl1->depth);
for (j=0; j<hh; j++)
for (i=0; i<ww; i++) {
int c = gl1->get_x (i, j);
int i2= i - gl1->xoff + gl2->xoff;
int j2= j - gl1->yoff + gl2->yoff;
if (i2 >= 0 && ww2 > i2 && j2 >= 0 && hh2 > j2)
c= min (c, gl2->get_x (i2, j2));
else c= 0;
bmr->set_x (i, j, c);
}
bmr->lwidth= gl1->lwidth;
return simplify (bmr);
}
glyph
exclude (glyph gl1, glyph gl2) {
int i, j;
int ww= gl1->width, hh= gl1->height, ww2= gl2->width, hh2= gl2->height;
glyph bmr (ww, hh, gl1->xoff, gl1->yoff, gl1->depth);
for (j=0; j<hh; j++)
for (i=0; i<ww; i++) {
int c = gl1->get_x (i, j);
int i2= i - gl1->xoff + gl2->xoff;
int j2= j - gl1->yoff + gl2->yoff;
if (i2 >= 0 && ww2 > i2 && j2 >= 0 && hh2 > j2)
if (gl2->get_x (i2, j2) != 0) c= 0;
bmr->set_x (i, j, c);
}
bmr->lwidth= gl1->lwidth;
return simplify (bmr);
}
glyph
bar_right (glyph gl1, glyph gl2) {
int ww1= gl1->width, hh1= gl1->height;
if (ww1 == 0 || hh1 == 0) return gl1;
int i, j;
int r1= 0, rj1= 0, r2= 0, rj2= hh1-1;
for (j=0; j<(hh1>>1); j++)
if (last_in_row (gl1, j) > r1) {
r1= last_in_row (gl1, j); rj1= j; }
for (j=hh1-1; j>=(hh1>>1); j--)
if (last_in_row (gl1, j) > r2) {
r2= last_in_row (gl1, j); rj2= j; }
glyph filled= copy (gl1);
for (j= rj1; j <= rj2; j++)
for (i= max (last_in_row (gl1, j), 0); i<ww1; i++)
filled->set_x (i, j, 1);
return join (gl1, intersect (gl2, filled));
}
glyph
bar_bottom (glyph gl1, glyph gl2) {
int ww1= gl1->width, hh1= gl1->height;
if (ww1 == 0 || hh1 == 0) return gl1;
int i, j;
int b1= 0, bi1= 0, b2= 0, bi2= ww1-1;
for (i=0; i<(ww1>>1); i++)
if (last_in_column (gl1, i) > b1) {
b1= last_in_column (gl1, i); bi1= i; }
for (i=ww1-1; i>=(ww1>>1); i--)
if (last_in_column (gl1, i) > b2) {
b2= last_in_column (gl1, i); bi2= i; }
glyph filled= copy (gl1);
for (i= bi1; i <= bi2; i++)
for (j= max (last_in_column (gl1, i), 0); j<hh1; j++)
filled->set_x (i, j, 1);
return join (gl1, intersect (gl2, filled));
}
/******************************************************************************
* Operating on glyphs
******************************************************************************/
glyph
copy (glyph gl) {
int i, j;
int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth);
for (j=0; j<hh; j++)
for (i=0; i<ww; i++)
bmr->set_x (i, j, gl->get_x (i, j));
return bmr;
}
glyph
simplify (glyph gl) {
int i, j;
int ww= gl->width, hh= gl->height;
int i1= 0, i2= ww-1, j1= 0, j2= hh-1;
while (i1 < ww && empty_column (gl, i1)) i1++;
while (i2 >= 0 && empty_column (gl, i2)) i2--;
while (j1 < hh && empty_row (gl, j1)) j1++;
while (j2 >= 0 && empty_row (gl, j2)) j2--;
if (i1 == ww) { i1= j1= 0; i2= j2= -1; }
glyph bmr (i2-i1+1, j2-j1+1, gl->xoff-i1, gl->yoff-j1, gl->depth);
for (j=j1; j<=j2; j++)
for (i=i1; i<=i2; i++)
bmr->set_x (i-i1, j-j1, gl->get_x (i, j));
bmr->lwidth= gl->lwidth;
return bmr;
}
glyph
padded (glyph gl, int l, int t, int r, int b) {
int i, j;
int ww= gl->width, hh= gl->height;
glyph bmr (ww+l+r, hh+t+b, gl->xoff+l, gl->yoff+t, gl->depth);
for (j=0; j<hh+t+b; j++)
for (i=0; i<ww+l+r; i++)
bmr->set_x (i, j, 0);
for (j=0; j<hh; j++)
for (i=0; i<ww; i++)
bmr->set_x (i + l, j + t, gl->get_x (i, j));
bmr->lwidth= gl->lwidth;
return bmr; return bmr;
} }
glyph glyph
move (glyph gl, SI x, SI y) { move (glyph gl, SI x, SI y) {
x += PIXEL/2; y += PIXEL/2; abs_round (x, y); x += PIXEL/2; y += PIXEL/2; abs_round (x, y);
int xx= x/PIXEL, yy= y/PIXEL; int xx= x/PIXEL, yy= y/PIXEL;
int ww= gl->width, hh= gl->height; int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh, gl->xoff- xx, gl->yoff+ yy, gl->depth); glyph bmr (ww, hh, gl->xoff- xx, gl->yoff+ yy, gl->depth);
skipping to change at line 68 skipping to change at line 323
x2= x2/PIXEL; y2= y2/PIXEL; x2= x2/PIXEL; y2= y2/PIXEL;
int i, j; int i, j;
int ww= gl->width, hh= gl->height; int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth); glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth);
for (j=0; j<hh; j++) for (j=0; j<hh; j++)
for (i=0; i<ww; i++) { for (i=0; i<ww; i++) {
bool x_ok= (i-gl->xoff >= x1) && (i-gl->xoff < x2); bool x_ok= (i-gl->xoff >= x1) && (i-gl->xoff < x2);
bool y_ok= (gl->yoff-j >= y1) && (gl->yoff-j < y2); bool y_ok= (gl->yoff-j >= y1) && (gl->yoff-j < y2);
bmr->set_x (i, j, x_ok && y_ok? gl->get_x (i, j): 0); bmr->set_x (i, j, x_ok && y_ok? gl->get_x (i, j): 0);
} }
return bmr; bmr->lwidth= gl->lwidth;
return simplify (bmr);
} }
glyph glyph
hor_flip (glyph gl) { hor_flip (glyph gl) {
int i, j; int i, j;
int ww= gl->width, hh= gl->height; int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth); glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth);
for (j=0; j<hh; j++) for (j=0; j<hh; j++)
for (i=0; i<ww; i++) for (i=0; i<ww; i++)
bmr->set_x (ww-1-i, j, gl->get_x (i, j)); bmr->set_x (ww-1-i, j, gl->get_x (i, j));
skipping to change at line 96 skipping to change at line 352
int ww= gl->width, hh= gl->height; int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth); glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth);
for (j=0; j<hh; j++) for (j=0; j<hh; j++)
for (i=0; i<ww; i++) for (i=0; i<ww; i++)
bmr->set_x (i, hh-1-j, gl->get_x (i, j)); bmr->set_x (i, hh-1-j, gl->get_x (i, j));
bmr->lwidth= gl->lwidth; bmr->lwidth= gl->lwidth;
return bmr; return bmr;
} }
glyph glyph
transpose (glyph gl) {
int i, j;
int ww= gl->width, hh= gl->height;
glyph bmr (hh, ww, gl->yoff, gl->xoff, gl->depth);
for (j=0; j<hh; j++)
for (i=0; i<ww; i++)
bmr->set_x (j, i, gl->get_x (i, j));
bmr->lwidth= gl->lwidth;
return bmr;
}
glyph
pos_rotate (glyph gl) { pos_rotate (glyph gl) {
int i, j; int i, j;
int ww= gl->width, hh= gl->height; int ww= gl->width, hh= gl->height;
glyph bmr (hh, ww, gl->yoff, gl->width- gl->xoff, gl->depth); glyph bmr (hh, ww, gl->yoff, gl->width- gl->xoff, gl->depth);
for (j=0; j<hh; j++) for (j=0; j<hh; j++)
for (i=0; i<ww; i++) for (i=0; i<ww; i++)
bmr->set_x (j, ww-1-i, gl->get_x (i, j)); bmr->set_x (j, ww-1-i, gl->get_x (i, j));
return bmr; return bmr;
} }
skipping to change at line 139 skipping to change at line 407
while (!ok) { // hack for corrupted pfb translations while (!ok) { // hack for corrupted pfb translations
for (j=0; j<hh; j++) for (j=0; j<hh; j++)
ok= ok || (gl->get_x (pos, j) != 0); ok= ok || (gl->get_x (pos, j) != 0);
if (!ok) pos += (pos < (ww>>1)? 1: -1); if (!ok) pos += (pos < (ww>>1)? 1: -1);
if (pos >= (ww>>2) && pos < (3*ww>>2)) break; if (pos >= (ww>>2) && pos < (3*ww>>2)) break;
} }
glyph bmr (nr, hh, 0, gl->yoff, gl->depth); glyph bmr (nr, hh, 0, gl->yoff, gl->depth);
for (j=0; j<hh; j++) for (j=0; j<hh; j++)
for (i=0; i<nr; i++) for (i=0; i<nr; i++)
bmr->set_x (i, j, gl->get_x (pos, j)); bmr->set_x (i, j, gl->get_x (pos, j));
return bmr; return simplify (bmr);
} }
glyph glyph
ver_extend (glyph gl, int pos, int by) { ver_extend (glyph gl, int pos, int by) {
int i, j; int i, j;
int ww= gl->width, hh= gl->height; int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh+by, gl->xoff, gl->yoff, gl->depth); glyph bmr (ww, hh+by, gl->xoff, gl->yoff, gl->depth);
for (j=0; j<(hh+by); j++) for (j=0; j<(hh+by); j++)
for (i=0; i<ww; i++) for (i=0; i<ww; i++)
bmr->set_x (i, j, gl->get_x (i, j<pos? j: (j<pos+by? pos: j-by))); bmr->set_x (i, j, gl->get_x (i, j<pos? j: (j<pos+by? pos: j-by)));
bmr->lwidth= gl->lwidth;
return bmr; return bmr;
} }
glyph glyph
ver_take (glyph gl, int pos, int nr) { ver_take (glyph gl, int pos, int nr) {
int i, j; int i, j;
int ww= gl->width; int ww= gl->width;
glyph bmr (ww, nr, gl->xoff, 0, gl->depth); glyph bmr (ww, nr, gl->xoff, 0, gl->depth);
for (j=0; j<nr; j++) for (j=0; j<nr; j++)
for (i=0; i<ww; i++) for (i=0; i<ww; i++)
bmr->set_x (i, j, gl->get_x (i, pos)); bmr->set_x (i, j, gl->get_x (i, pos));
bmr->lwidth= gl->lwidth;
return simplify (bmr);
}
glyph
bottom_edge (glyph gl, SI penh, SI keepy) {
int ph= (penh + PIXEL - 1) / PIXEL;
int kj= gl->yoff - (keepy + (PIXEL >> 1)) / PIXEL;
int i, j;
int ww= gl->width, hh= gl->height;
glyph bmr (ww, hh, gl->xoff, gl->yoff, gl->depth);
for (i=0; i<ww; i++) {
int j2= last_in_column (gl, i);
int j1= min (j2 - ph, kj);
bool ok= j2 > 0 && j2 > (kj - (ph >> 1));
for (j=0; j<hh; j++)
if (ok && j > j1 && j2 >= j)
bmr->set_x (i, j, gl->get_x (i, j));
else bmr->set_x (i, j, 0);
}
bmr->lwidth= gl->lwidth;
return simplify (bmr);
}
glyph
flood_fill (glyph gl, SI px, SI py) {
gl= simplify (gl);
glyph bmr= copy (gl);
int ww= gl->width, hh= gl->height;
int pi= gl->xoff + (px + (PIXEL >> 1)) / PIXEL;
int pj= gl->yoff - (py + (PIXEL >> 1)) / PIXEL;
if (pi < 0) pi= 0;
if (pi >= ww) pi= ww-1;
if (pj < 0) pi= 0;
if (pj >= hh) pj= hh-1;
array<int> todo;
todo << pi << pj;
array<int> next;
while (N(todo) != 0) {
for (int k=0; k+1<N(todo); k+=2) {
int i= todo[k], j= todo[k+1];
if ((i < ww) && (i >= 0) && (j < hh) && (j >= 0))
if (bmr->get_x (i, j) == 0) {
bmr->set_x (i, j, 1);
next << i+1 << j << i-1 << j << i << j+1 << i << j-1;
}
}
todo= next;
next= array<int> ();
}
bmr->lwidth= gl->lwidth;
return bmr; return bmr;
} }
/******************************************************************************
* Miscellaneous glyphs
******************************************************************************/
glyph
circle_glyph (SI rad, SI penw) {
int rr= (rad + (penw >> 1)) / PIXEL + 1;
int ww= 2*rr-1, hh= 2*rr-1;
glyph bmr (ww, hh, rr, rr, 1);
for (int i=0; i<ww; i++)
for (int j=0; j<hh; j++) {
double x= (double) ((i - rr) * PIXEL);
double y= (double) ((j - rr) * PIXEL);
SI d= (SI) ceil (sqrt (x*x + y*y));
if ((rad + (penw >> 1)) > d && (d >= rad - (penw >> 1)))
bmr->set_x (i, j, 1);
else bmr->set_x (i, j, 0);
}
return simplify (bmr);
}
 End of changes. 8 change blocks. 
2 lines changed or deleted 323 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS