PageRenderTime 45ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/bristol-0.60.10/libbvg/bvg.c

#
C | 625 lines | 456 code | 94 blank | 75 comment | 195 complexity | 3c4183362ec32f3ae213d533e3776928 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * We are going to take a file format and convert the content into a bitmap
  3. * array based on basic (bristol) vector graphics. The main goal is to render
  4. * silkscreen bitmaps for fonts, the overlays for the synths.
  5. *
  6. * The graphics will be referenced on 1000 by 1000 arrays? No, the format
  7. * should include it's rough layout. We should have a subformat for fonts so
  8. * we can call 'font/size' for example. We need a 'fill' option for boxes, a
  9. * line option, each should include a color.
  10. *
  11. * Type: line, linearray, fill, <sub>
  12. * color: 0xAARRGGBB
  13. * coord: x/y
  14. */
  15. #include <stdio.h>
  16. #include <math.h>
  17. #include <brightoninternals.h>
  18. #include <font1.h>
  19. #ifndef ANDROID_COLORS
  20. static brightonWindow *bwin;
  21. #endif
  22. /*
  23. * We have the bitmap, we are given an area on that bitmap, we now render the
  24. * fill into that area.
  25. */
  26. static void
  27. bvgRenderFill(brightonBitmap *bm, bvgImage *image, int stage,
  28. int ox, int oy, int ow, int oh)
  29. {
  30. float sx, sy, ex, ey;
  31. float x, y;
  32. int c = image->element[stage].line.color;
  33. #ifndef ANDROID_COLORS
  34. c = brightonGetGC(bwin,
  35. (c>>8) & 0x0000ff00,
  36. c & 0x0000ff00,
  37. (c << 8) & 0x0000ff00);
  38. #endif
  39. /*
  40. * Starting X point: origin-x + stage-x * stage-w / bitmap-w
  41. */
  42. if ((sx = ox + image->element[stage].line.x * ow / image->width)
  43. >= bm->width)
  44. return;
  45. /*
  46. * Starting Y point: origin-y + stage-y * stage-h / bitmap-h
  47. */
  48. if ((sy = oy + image->element[stage].line.y * oh / image->height)
  49. >= bm->height)
  50. return;
  51. /*
  52. * Ending X point: origin-x + stage-x * stage-w / bitmap-w
  53. */
  54. if ((ex = ox + image->element[stage].line.X * ow / image->width)
  55. >= bm->width)
  56. return;
  57. /*
  58. * Ending Y point: origin-y + stage-y * stage-h / bitmap-h
  59. */
  60. if ((ey = oy + image->element[stage].line.Y * oh / image->height)
  61. >= bm->height)
  62. return;
  63. // Normalise
  64. if (sx > ex)
  65. {
  66. float tx = ex;
  67. ex = sx;
  68. sx = tx;
  69. }
  70. // Normalise
  71. if (sy > ey)
  72. {
  73. float ty = ey;
  74. ey = sy;
  75. sy = ty;
  76. }
  77. for (x = sx; x <= ex; x += 1)
  78. {
  79. for (y = sy; y <= ey; y += 1)
  80. {
  81. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  82. break;
  83. // Set pixel x, y
  84. //printf("set %i %i\n", (int) x, (int) y);
  85. bm->pixels[(int) (round(x) + ((int) y) * bm->width)] = c;
  86. }
  87. }
  88. }
  89. static void
  90. bvgSetPoint(brightonBitmap *bm, int style, int x, int y, int c)
  91. {
  92. int nx, ny;
  93. for (nx = 0; nx < style; nx++)
  94. for (ny = 0; ny < style; ny++)
  95. bm->pixels[nx + x + (ny + y) * bm->width] = c;
  96. }
  97. /*
  98. * We have the bitmap, we are given an area on that bitmap, we now render the
  99. * line into that area.
  100. */
  101. static int
  102. bvgRenderVector(brightonBitmap *bm, bvgImage *image, bvgVect *v, int c,
  103. int style, int ox, int oy, int ow, int oh)
  104. {
  105. float sx, sy, ex, ey;
  106. float dx, dy;
  107. float x, y;
  108. int i, startx, starty, w = 0;
  109. if (style <= 0)
  110. style = 1;
  111. if (v->count < 2)
  112. return(0);
  113. #ifndef ANDROID_COLORS
  114. c = brightonGetGC(bwin,
  115. (c>>8) & 0x0000ff00,
  116. c & 0x0000ff00,
  117. (c << 8) & 0x0000ff00);
  118. #endif
  119. /*
  120. * Starting X point: origin-x + stage-x * stage-w / bitmap-w
  121. if ((sx = ox + v->coords[0].x * ow / image->width)
  122. */
  123. if ((sx = ox * bm->width / image->width) >= bm->width)
  124. return(0);
  125. /*
  126. * Starting Y point: origin-y + stage-y * stage-h / bitmap-h
  127. if ((sy = oy + v->coords[0].y * oh / image->height)
  128. */
  129. if ((sy = oy * bm->height / image->height) >= bm->height)
  130. return(0);
  131. startx = sx;
  132. starty = sy;
  133. if ((sx = startx + ow * v->coords[0].x * bm->width / (image->width * 100))
  134. >= bm->width)
  135. return(0);
  136. if ((sy = starty + oh * v->coords[0].y * bm->height / (image->height * 100))
  137. >= bm->height)
  138. return(0);
  139. for (i = 1; i < v->count; i++)
  140. {
  141. if (v->coords[i].x < 0)
  142. {
  143. if (++i >= v->count)
  144. return(0);
  145. if ((sx = startx + ow * v->coords[i].x * bm->width / (image->width * 100))
  146. >= bm->width)
  147. return(0);
  148. if ((sy = starty + oh * v->coords[i].y * bm->height / (image->height * 100))
  149. >= bm->height)
  150. return(0);
  151. continue;
  152. }
  153. /*
  154. * Ending X point: origin-x + stage-x * stage-w / bitmap-w
  155. */
  156. if ((ex = startx + ow * v->coords[i].x * bm->width / (image->width * 100))
  157. >= bm->width)
  158. return(w - startx);
  159. /*
  160. * Ending Y point: origin-y + stage-y * stage-h / bitmap-h
  161. */
  162. if ((ey = starty + oh * v->coords[i].y * bm->height / (image->height * 100))
  163. >= bm->height)
  164. return(w - startx);
  165. if (ex > w) w = ex;
  166. /*
  167. * There are 8 cases we need to check for with 4 net actions
  168. */
  169. if ((sx <= ex) && (sy <= ey) && ((ex - sx) >= (ey - sy)))
  170. {
  171. dy = ((float) (ey - sy)) / (ex - sx);
  172. y = sy;
  173. for (x = sx; x <= ex; x += 1)
  174. {
  175. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  176. break;
  177. bvgSetPoint(bm, style, round(x), round(y), c);
  178. y += dy;
  179. }
  180. } else if ((sx <= ex) && (sy > ey) && ((ex - sx) >= (sy - ey))) {
  181. dy = ((float) (ey - sy)) / (ex - sx);
  182. y = sy;
  183. for (x = sx; x <= ex; x += 1)
  184. {
  185. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  186. break;
  187. bvgSetPoint(bm, style, round(x), round(y), c);
  188. y += dy;
  189. }
  190. } else if ((sx >= ex) && (sy <= ey) && ((sx - ex) >= (ey - sy))) {
  191. dy = ((float) (sy - ey)) / (ex - sx);
  192. y = sy;
  193. for (x = sx; x >= ex; x -= 1)
  194. {
  195. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  196. break;
  197. bvgSetPoint(bm, style, round(x), round(y), c);
  198. y += dy;
  199. }
  200. } else if ((sx >= ex) && (sy >= ey) && ((sx - ex) >= (sy - ey))) {
  201. dy = ((float) (sy - ey)) / (ex - sx);
  202. y = sy;
  203. for (x = sx; x >= ex; x -= 1)
  204. {
  205. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  206. break;
  207. bvgSetPoint(bm, style, round(x), round(y), c);
  208. y += dy;
  209. }
  210. } else if ((sx <= ex) && (sy <= ey) && ((ex - sx) <= (ey - sy))) {
  211. dx = ((float) (ex - sx)) / (ey - sy);
  212. x = sx;
  213. for (y = sy; y <= ey; y += 1)
  214. {
  215. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  216. break;
  217. bvgSetPoint(bm, style, round(x), round(y), c);
  218. x += dx;
  219. }
  220. } else if ((sx >= ex) && (sy <= ey) && ((sx - ex) <= (ey - sy))) {
  221. dx = ((float) (ex - sx)) / (ey - sy);
  222. x = sx;
  223. for (y = sy; y <= ey; y += 1)
  224. {
  225. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  226. break;
  227. bvgSetPoint(bm, style, round(x), round(y), c);
  228. x += dx;
  229. }
  230. } else if ((sx <= ex) && (sy > ey) && ((ex - sx) >= (sy - ey))) {
  231. dx = ((float) (sx - ex)) / (ey - sy);
  232. x = sx;
  233. for (y = sy; y >= ey; y -= 1)
  234. {
  235. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  236. break;
  237. bvgSetPoint(bm, style, round(x), round(y), c);
  238. x += dx;
  239. }
  240. } else {
  241. dx = ((float) (sx - ex)) / (ey - sy);
  242. x = sx;
  243. for (y = sy; y >= ey; y -= 1)
  244. {
  245. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  246. break;
  247. bvgSetPoint(bm, style, round(x), round(y), c);
  248. x += dx;
  249. }
  250. }
  251. sx = ex;
  252. sy = ey;
  253. }
  254. return(w - startx);
  255. }
  256. /*
  257. * We have the bitmap, we are given an area on that bitmap, we now render the
  258. * line into that area.
  259. */
  260. static void
  261. bvgRenderLine(brightonBitmap *bm, bvgImage *image, int stage,
  262. int ox, int oy, int ow, int oh)
  263. {
  264. float sx, sy, ex, ey;
  265. float dx, dy;
  266. float x, y;
  267. int c = image->element[stage].line.color;
  268. int style = image->element[stage].line.type & BVG_STYLE_MASK;
  269. if (style <= 0)
  270. style = 1;
  271. #ifndef ANDROID_COLORS
  272. c = brightonGetGC(bwin,
  273. (c>>8) & 0x0000ff00,
  274. c & 0x0000ff00,
  275. (c << 8) & 0x0000ff00);
  276. #endif
  277. /*
  278. * Starting X point: origin-x + stage-x * stage-w / bitmap-w
  279. */
  280. if ((sx = ox + image->element[stage].line.x * ow / image->width)
  281. >= bm->width)
  282. return;
  283. /*
  284. * Starting Y point: origin-y + stage-y * stage-h / bitmap-h
  285. */
  286. if ((sy = oy + image->element[stage].line.y * oh / image->height)
  287. >= bm->height)
  288. return;
  289. /*
  290. * Ending X point: origin-x + stage-x * stage-w / bitmap-w
  291. */
  292. if ((ex = ox + image->element[stage].line.X * ow / image->width)
  293. >= bm->width)
  294. return;
  295. /*
  296. * Ending Y point: origin-y + stage-y * stage-h / bitmap-h
  297. */
  298. if ((ey = oy + image->element[stage].line.Y * oh / image->height)
  299. >= bm->height)
  300. return;
  301. /*
  302. * There are 8 cases we need to check for with 4 net actions
  303. */
  304. if ((sx <= ex) && (sy <= ey) && ((ex - sx) >= (ey - sy)))
  305. {
  306. dy = ((float) (ey - sy)) / (ex - sx);
  307. y = sy;
  308. for (x = sx; x <= ex; x += 1)
  309. {
  310. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  311. break;
  312. bvgSetPoint(bm, style, round(x), round(y), c);
  313. y += dy;
  314. }
  315. } else if ((sx <= ex) && (sy > ey) && ((ex - sx) >= (sy - ey))) {
  316. dy = ((float) (ey - sy)) / (ex - sx);
  317. y = sy;
  318. for (x = sx; x <= ex; x += 1)
  319. {
  320. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  321. break;
  322. bvgSetPoint(bm, style, round(x), round(y), c);
  323. y += dy;
  324. }
  325. } else if ((sx >= ex) && (sy <= ey) && ((sx - ex) >= (ey - sy))) {
  326. dy = ((float) (sy - ey)) / (ex - sx);
  327. y = sy;
  328. for (x = sx; x >= ex; x -= 1)
  329. {
  330. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  331. break;
  332. bvgSetPoint(bm, style, round(x), round(y), c);
  333. y += dy;
  334. }
  335. } else if ((sx >= ex) && (sy >= ey) && ((sx - ex) >= (sy - ey))) {
  336. dy = ((float) (sy - ey)) / (ex - sx);
  337. y = sy;
  338. for (x = sx; x >= ex; x -= 1)
  339. {
  340. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  341. break;
  342. bvgSetPoint(bm, style, round(x), round(y), c);
  343. y += dy;
  344. }
  345. } else if ((sx <= ex) && (sy <= ey) && ((ex - sx) <= (ey - sy))) {
  346. dx = ((float) (ex - sx)) / (ey - sy);
  347. x = sx;
  348. for (y = sy; y <= ey; y += 1)
  349. {
  350. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  351. break;
  352. bvgSetPoint(bm, style, round(x), round(y), c);
  353. x += dx;
  354. }
  355. } else if ((sx >= ex) && (sy <= ey) && ((sx - ex) <= (ey - sy))) {
  356. dx = ((float) (ex - sx)) / (ey - sy);
  357. x = sx;
  358. for (y = sy; y <= ey; y += 1)
  359. {
  360. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  361. break;
  362. bvgSetPoint(bm, style, round(x), round(y), c);
  363. x += dx;
  364. }
  365. } else if ((sx <= ex) && (sy > ey) && ((ex - sx) >= (sy - ey))) {
  366. dx = ((float) (sx - ex)) / (ey - sy);
  367. x = sx;
  368. for (y = sy; y >= ey; y -= 1)
  369. {
  370. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  371. break;
  372. bvgSetPoint(bm, style, round(x), round(y), c);
  373. x += dx;
  374. }
  375. } else {
  376. dx = ((float) (sx - ex)) / (ey - sy);
  377. x = sx;
  378. for (y = sy; y >= ey; y -= 1)
  379. {
  380. if ((x < 0) || (y < 0) || (x >= bm->width) || (y >= bm->height))
  381. break;
  382. bvgSetPoint(bm, style, round(x), round(y), c);
  383. x += dx;
  384. }
  385. }
  386. }
  387. static void
  388. bvgRenderString(brightonBitmap *bm, bvgImage *image, int stage,
  389. int ox, int oy, int ow, int oh)
  390. {
  391. int i = 0, step, len;
  392. len = strlen(image->element[stage].string.string);
  393. step = ow / len - 1;
  394. ow = step - 1;
  395. while (image->element[stage].string.string[i] != '\0')
  396. {
  397. if (image->element[stage].string.string[i] != ' ')
  398. bvgRenderVector(bm, image,
  399. font1[(int) image->element[stage].string.string[i]],
  400. image->element[stage].line.color,
  401. image->element[stage].line.type & BVG_STYLE_MASK,
  402. ox, oy, ow, oh);
  403. ox += step;
  404. i++;
  405. }
  406. }
  407. extern iMap imageMap[];
  408. bvgImage *
  409. findImage(char *name)
  410. {
  411. int i = 0;
  412. if (name == NULL)
  413. return(NULL);
  414. while (imageMap[i].image != NULL)
  415. {
  416. if (strcmp(name, imageMap[i].name) == 0)
  417. return(imageMap[i].image);
  418. i++;
  419. }
  420. return NULL;
  421. }
  422. static void
  423. bvgMacro(brightonBitmap *bm, bvgImage *image, int x, int y, int w, int h)
  424. {
  425. int stage;
  426. if (image == NULL)
  427. return;
  428. for (stage = 0; stage < image->count; stage++)
  429. {
  430. switch (image->element[stage].line.type & BVG_TYPE_MASK) {
  431. case BVG_LINE:
  432. bvgRenderLine(bm, image, stage, x, y, w, h);
  433. break;
  434. case BVG_SQUARE:
  435. bvgRenderFill(bm, image, stage, x, y, w, h);
  436. break;
  437. case BVG_STRING:
  438. bvgRenderString(bm, image, stage,
  439. x + image->element[stage].string.x * w / 100,
  440. y + image->element[stage].string.y * h / 100,
  441. image->element[stage].string.W * w / 100,
  442. image->element[stage].string.H * h / 100);
  443. break;
  444. case BVG_VECT:
  445. bvgRenderVector(bm, image,
  446. image->element[stage].vector.vector,
  447. image->element[stage].line.color,
  448. image->element[stage].line.type & BVG_STYLE_MASK,
  449. x + image->element[stage].vector.x * w / 100,
  450. y + image->element[stage].vector.y * h / 100,
  451. image->element[stage].vector.W * w / 100,
  452. image->element[stage].vector.H * h / 100);
  453. break;
  454. }
  455. }
  456. }
  457. int
  458. bvgRender(brightonBitmap *bm, bvgImage *image, int x, int y, int w, int h)
  459. {
  460. int stage;
  461. if (image == NULL)
  462. return(0);
  463. if (image->color != 0)
  464. memset(bm->pixels, 0, bm->width * bm->height * sizeof(int));
  465. for (stage = 0; stage < image->count; stage++)
  466. {
  467. switch (image->element[stage].line.type & BVG_TYPE_MASK) {
  468. case BVG_LINE:
  469. bvgRenderLine(bm, image, stage, x, y, w, h);
  470. break;
  471. case BVG_SQUARE:
  472. bvgRenderFill(bm, image, stage, x, y, w, h);
  473. break;
  474. case BVG_STRING:
  475. bvgRenderString(bm, image, stage,
  476. image->element[stage].string.x,
  477. image->element[stage].string.y,
  478. image->element[stage].string.W,
  479. image->element[stage].string.H);
  480. break;
  481. case BVG_IMAGE:
  482. // This is recursion, take care with subimage coords
  483. bvgMacro(bm,
  484. image->element[stage].image.image,
  485. image->element[stage].image.x,
  486. image->element[stage].image.y,
  487. image->element[stage].image.w,
  488. image->element[stage].image.h);
  489. break;
  490. case BVG_VECT:
  491. bvgRenderVector(bm, image,
  492. image->element[stage].vector.vector,
  493. image->element[stage].line.color,
  494. image->element[stage].line.type & BVG_STYLE_MASK,
  495. image->element[stage].vector.x,
  496. image->element[stage].vector.y,
  497. image->element[stage].vector.W,
  498. image->element[stage].vector.H);
  499. break;
  500. }
  501. }
  502. return(0);
  503. }
  504. void
  505. bvgRenderInit(brightonWindow *bw)
  506. {
  507. #ifndef ANDROID_COLORS
  508. bwin = bw;
  509. #endif
  510. initFont1();
  511. }
  512. void
  513. bvgRenderInt(brightonWindow *bw, char *name, brightonBitmap *bm)
  514. {
  515. if ((bm == NULL) || (bm->pixels == NULL))
  516. return;
  517. if (font1[0] == NULL)
  518. bvgRenderInit(bw);
  519. bvgRender(bm, findImage(name), 0, 0, bm->width, bm->height);
  520. }
  521. #ifdef TESTING
  522. main()
  523. {
  524. brightonBitmap bm;
  525. bm.width = 788;
  526. bm.height = 244;
  527. bm.pixels = malloc(bm.width * bm.height * sizeof(int));
  528. bvgRender(&bm, &JunoImage, 0, 0, 788, 244);
  529. return(0);
  530. }
  531. #endif