summaryrefslogtreecommitdiffstats
path: root/src/libnr/nr-blit.cpp
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2006-01-16 02:36:01 +0000
committermental <mental@users.sourceforge.net>2006-01-16 02:36:01 +0000
commit179fa413b047bede6e32109e2ce82437c5fb8d34 (patch)
treea5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/libnr/nr-blit.cpp
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/libnr/nr-blit.cpp')
-rw-r--r--src/libnr/nr-blit.cpp300
1 files changed, 300 insertions, 0 deletions
diff --git a/src/libnr/nr-blit.cpp b/src/libnr/nr-blit.cpp
new file mode 100644
index 000000000..2a93bc9bd
--- /dev/null
+++ b/src/libnr/nr-blit.cpp
@@ -0,0 +1,300 @@
+#define __NR_BLIT_C__
+
+/*
+ * Pixel buffer rendering library
+ *
+ * Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ *
+ * This code is in public domain
+ */
+
+#include "nr-pixops.h"
+#include "nr-compose.h"
+#include "nr-blit.h"
+
+void
+nr_blit_pixblock_pixblock_alpha (NRPixBlock *d, NRPixBlock *s, unsigned int alpha)
+{
+ NRRectL clip;
+ unsigned char *dpx, *spx;
+ int dbpp, sbpp;
+ int w, h;
+
+ if (alpha == 0) return;
+ if (s->empty) return;
+ /* fixme: */
+ if (s->mode == NR_PIXBLOCK_MODE_A8) return;
+ /* fixme: */
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8) return;
+
+ /*
+ * Possible variants as of now:
+ *
+ * 0. SRC EP - DST EP *
+ * 1. SRC EP - DST EN *
+ * 2. SRC EP - DST P *
+ * 3. SRC EP - DST N *
+ * 4. SRC EN - DST EP *
+ * 5. SRC EN - DST EN *
+ * 6. SRC EN - DST P *
+ * 7. SRC EN - DST N *
+ * 8. SRC P - DST EP *
+ * 9. SRC P - DST EN *
+ * A. SRC P - DST P *
+ * B. SRC P - DST N *
+ * C. SRC N - DST EP *
+ * D. SRC N - DST EN *
+ * E. SRC N - DST P *
+ * F. SRC N - DST N *
+ *
+ */
+
+ nr_rect_l_intersect (&clip, &d->area, &s->area);
+
+ if (nr_rect_l_test_empty (&clip)) return;
+
+ /* Pointers */
+ dbpp = NR_PIXBLOCK_BPP (d);
+ dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + dbpp * (clip.x0 - d->area.x0);
+ sbpp = NR_PIXBLOCK_BPP (s);
+ spx = NR_PIXBLOCK_PX (s) + (clip.y0 - s->area.y0) * s->rs + sbpp * (clip.x0 - s->area.x0);
+ w = clip.x1 - clip.x0;
+ h = clip.y1 - clip.y0;
+
+ switch (d->mode) {
+ case NR_PIXBLOCK_MODE_A8:
+ /* No rendering into alpha at moment */
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8:
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ nr_R8G8B8_R8G8B8_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
+ } else {
+ nr_R8G8B8_R8G8B8_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
+ }
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8A8P:
+ if (d->empty) {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* Case 8 */
+ nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
+ } else {
+ /* Case C */
+ nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
+ }
+ } else {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* case A */
+ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
+ } else {
+ /* case E */
+ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
+ }
+ }
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8A8N:
+ if (d->empty) {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* Case 9 */
+ nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
+ } else {
+ /* Case D */
+ nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
+ }
+ } else {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* case B */
+ nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
+ } else {
+ /* case F */
+ nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
+ }
+ }
+ break;
+ }
+}
+
+void
+nr_blit_pixblock_pixblock_mask (NRPixBlock *d, NRPixBlock *s, NRPixBlock *m)
+{
+ NRRectL clip;
+ unsigned char *dpx, *spx, *mpx;
+ int dbpp, sbpp;
+ int w, h;
+
+ if (s->empty) return;
+ /* fixme: */
+ if (s->mode == NR_PIXBLOCK_MODE_A8) return;
+ /* fixme: */
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8) return;
+
+ /*
+ * Possible variants as of now:
+ *
+ * 0. SRC EP - DST EP *
+ * 1. SRC EP - DST EN *
+ * 2. SRC EP - DST P *
+ * 3. SRC EP - DST N *
+ * 4. SRC EN - DST EP *
+ * 5. SRC EN - DST EN *
+ * 6. SRC EN - DST P *
+ * 7. SRC EN - DST N *
+ * 8. SRC P - DST EP *
+ * 9. SRC P - DST EN *
+ * A. SRC P - DST P *
+ * B. SRC P - DST N *
+ * C. SRC N - DST EP *
+ * D. SRC N - DST EN *
+ * E. SRC N - DST P *
+ * F. SRC N - DST N *
+ *
+ */
+
+ nr_rect_l_intersect (&clip, &d->area, &s->area);
+ nr_rect_l_intersect (&clip, &clip, &m->area);
+
+ if (nr_rect_l_test_empty (&clip)) return;
+
+ /* Pointers */
+ dbpp = NR_PIXBLOCK_BPP (d);
+ dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + dbpp * (clip.x0 - d->area.x0);
+ sbpp = NR_PIXBLOCK_BPP (s);
+ spx = NR_PIXBLOCK_PX (s) + (clip.y0 - s->area.y0) * s->rs + sbpp * (clip.x0 - s->area.x0);
+ mpx = NR_PIXBLOCK_PX (m) + (clip.y0 - m->area.y0) * m->rs + 1 * (clip.x0 - m->area.x0);
+ w = clip.x1 - clip.x0;
+ h = clip.y1 - clip.y0;
+
+ switch (d->mode) {
+ case NR_PIXBLOCK_MODE_A8:
+ /* No rendering into alpha at moment */
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8:
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ nr_R8G8B8_R8G8B8_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ } else {
+ nr_R8G8B8_R8G8B8_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ }
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8A8P:
+ if (d->empty) {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* Case 8 */
+ nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ } else {
+ /* Case C */
+ nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ }
+ } else {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* case A */
+ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ } else {
+ /* case E */
+ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ }
+ }
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8A8N:
+ if (d->empty) {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* Case 9 */
+ nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ } else {
+ /* Case D */
+ nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ }
+ } else {
+ if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* case B */
+ nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ } else {
+ /* case F */
+ nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
+ }
+ }
+ break;
+ }
+}
+
+void
+nr_blit_pixblock_mask_rgba32 (NRPixBlock *d, NRPixBlock *m, unsigned long rgba)
+{
+ if (!(rgba & 0xff)) return;
+
+ if (m) {
+ NRRectL clip;
+ unsigned char *dpx, *mpx;
+ int w, h;
+
+ if (m->mode != NR_PIXBLOCK_MODE_A8) return;
+
+ if (!nr_rect_l_test_intersect (&d->area, &m->area)) return;
+
+ nr_rect_l_intersect (&clip, &d->area, &m->area);
+
+ /* Pointers */
+ dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + NR_PIXBLOCK_BPP (d) * (clip.x0 - d->area.x0);
+ mpx = NR_PIXBLOCK_PX (m) + (clip.y0 - m->area.y0) * m->rs + (clip.x0 - m->area.x0);
+ w = clip.x1 - clip.x0;
+ h = clip.y1 - clip.y0;
+
+ if (d->empty) {
+ if (d->mode == NR_PIXBLOCK_MODE_R8G8B8) {
+ nr_R8G8B8_R8G8B8_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
+ } else if (d->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ nr_R8G8B8A8_P_EMPTY_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
+ } else {
+ nr_R8G8B8A8_N_EMPTY_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
+ }
+ d->empty = 0;
+ } else {
+ if (d->mode == NR_PIXBLOCK_MODE_R8G8B8) {
+ nr_R8G8B8_R8G8B8_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
+ } else if (d->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
+ } else {
+ nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
+ }
+ }
+ } else {
+ unsigned int r, g, b, a;
+ int x, y;
+ r = NR_RGBA32_R (rgba);
+ g = NR_RGBA32_G (rgba);
+ b = NR_RGBA32_B (rgba);
+ a = NR_RGBA32_A (rgba);
+ for (y = d->area.y0; y < d->area.y1; y++) {
+ unsigned char *p;
+ p = NR_PIXBLOCK_PX (d) + (y - d->area.y0) * d->rs;
+ for (x = d->area.x0; x < d->area.x1; x++) {
+ unsigned int da;
+ switch (d->mode) {
+ case NR_PIXBLOCK_MODE_R8G8B8:
+ p[0] = NR_COMPOSEN11 (r, a, p[0]);
+ p[1] = NR_COMPOSEN11 (g, a, p[1]);
+ p[2] = NR_COMPOSEN11 (b, a, p[2]);
+ p += 3;
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8A8P:
+ p[0] = NR_COMPOSENPP (r, a, p[0], p[3]);
+ p[1] = NR_COMPOSENPP (g, a, p[1], p[3]);
+ p[2] = NR_COMPOSENPP (b, a, p[2], p[3]);
+ p[3] = (65025 - (255 - a) * (255 - p[3]) + 127) / 255;
+ p += 4;
+ break;
+ case NR_PIXBLOCK_MODE_R8G8B8A8N:
+ da = 65025 - (255 - a) * (255 - p[3]);
+ p[0] = NR_COMPOSENNN_A7 (r, a, p[0], p[3], da);
+ p[1] = NR_COMPOSENNN_A7 (g, a, p[1], p[3], da);
+ p[2] = NR_COMPOSENNN_A7 (b, a, p[2], p[3], da);
+ p[3] = (da + 127) / 255;
+ p += 4;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
+