summaryrefslogtreecommitdiff
path: root/src/drivers/Android
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/Android')
-rw-r--r--src/drivers/Android/Fl_Android_Application.H16
-rw-r--r--src/drivers/Android/Fl_Android_Application.cxx1
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.H47
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.cxx447
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Font.cxx6
5 files changed, 484 insertions, 33 deletions
diff --git a/src/drivers/Android/Fl_Android_Application.H b/src/drivers/Android/Fl_Android_Application.H
index dc5838525..20862ab46 100644
--- a/src/drivers/Android/Fl_Android_Application.H
+++ b/src/drivers/Android/Fl_Android_Application.H
@@ -245,22 +245,6 @@ private:
};
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * This is the function that application code must implement, representing
- * the main entry to the app.
- */
-extern int main(int argc, char **argv);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
#endif // FL_ANDROID_APPLICATION_H
//
diff --git a/src/drivers/Android/Fl_Android_Application.cxx b/src/drivers/Android/Fl_Android_Application.cxx
index c1d69b9f8..97b692199 100644
--- a/src/drivers/Android/Fl_Android_Application.cxx
+++ b/src/drivers/Android/Fl_Android_Application.cxx
@@ -25,6 +25,7 @@
#include "Fl_Android_Application.H"
#include "Fl_Android_Window_Driver.H"
+#include <FL/platform.H>
#include <FL/fl_draw.H>
#include <jni.h>
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H
index dcfd27446..95d97880a 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H
@@ -41,6 +41,13 @@ class Fl_Android_Bytemap;
*/
class FL_EXPORT Fl_Android_Graphics_Driver : public Fl_Scalable_Graphics_Driver
{
+ class Vertex {
+ public:
+ void set(float x, float y, bool gap = false) { pX = x; pY = y; pIsGap = gap; }
+ float pX, pY;
+ bool pIsGap;
+ };
+
public:
Fl_Android_Graphics_Driver();
virtual ~Fl_Android_Graphics_Driver() override;
@@ -62,15 +69,34 @@ public:
virtual Fl_Font set_fonts(const char *name) override;
virtual void font_name(int num, const char *name) override;
- // --- line drawinf stuff
+ // --- line drawing stuff
virtual void rectf_unscaled(float x, float y, float w, float h) override;
void rectf_unclipped(float x, float y, float w, float h);
virtual void point_unscaled(float x, float y) override;
- void rect_unscaled(float x, float y, float w, float h);
+ virtual void rect_unscaled(float x, float y, float w, float h) override;
virtual void xyline_unscaled(float x, float y, float x1) override;
void xyline_unclipped(float x, float y, float x1);
virtual void yxline_unscaled(float x, float y, float y1) override;
void yxline_unclipped(float x, float y, float y1);
+ virtual void line_unscaled(float x, float y, float x1, float y1) override;
+
+ // --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
+ virtual void begin_points() override;
+ virtual void begin_line() override;
+ virtual void begin_loop() override;
+ virtual void begin_polygon() override;
+ virtual void begin_complex_polygon() override;
+ virtual void end_points() override;
+ virtual void end_line() override;
+ virtual void end_loop() override;
+ virtual void end_polygon() override;
+ void end_polygon(int begin, int end);
+ virtual void end_complex_polygon() override;
+ virtual void gap() override;
+ virtual void transformed_vertex0(float x, float y) override;
+
+ virtual void arc_unscaled(float x, float y, float w, float h, double a1, double a2);
+ virtual void pie_unscaled(float x, float y, float w, float h, double a1, double a2);
// --- clipping
virtual void push_clip(int x, int y, int w, int h) override;
@@ -118,30 +144,18 @@ public:
static HRGN scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr);
virtual void scale(float f);
protected:
- void transformed_vertex0(float x, float y);
void fixloop();
// --- implementation is in src/fl_rect.cxx which includes src/cfg_gfx/gdi_rect.cxx
- virtual void line_unscaled(float x, float y, float x1, float y1);
virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
virtual Fl_Region scale_clip(float f);
- // --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
- void begin_complex_polygon();
- void end_points();
- void end_line();
- void end_loop();
- void end_polygon();
- void end_complex_polygon();
- void gap();
virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
// --- implementation is in src/fl_arc.cxx which includes src/cfg_gfx/xxx_arc.cxx if needed
// using void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end);
// --- implementation is in src/fl_arci.cxx which includes src/cfg_gfx/xxx_arci.cxx
- virtual void arc_unscaled(float x, float y, float w, float h, double a1, double a2);
- virtual void pie_unscaled(float x, float y, float w, float h, double a1, double a2);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
virtual void line_style_unscaled(int style, float width, char* dashes);
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
@@ -176,6 +190,11 @@ protected:
// Final clipping region for all graphics calls to this class.
Fl_Complex_Region pClippingRegion;
+
+ void begin_vertices();
+ void add_vertex(float x, float y, bool gap=false);
+ int pnVertex = 0, pNVertex = 0, pVertexGapStart = 0;
+ Vertex *pVertex = nullptr;
};
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
index 71ffa6224..fbd85fc34 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
@@ -24,7 +24,9 @@
#include <FL/Fl.H>
#include <FL/platform.H>
#include <errno.h>
+#include <math.h>
+static int sign(int v) { return (v<0) ? -1 : 1; }
/*
* By linking this module, the following static method will instantiate the
@@ -229,6 +231,451 @@ void Fl_Android_Graphics_Driver::point_unscaled(float x, float y)
}
+/**
+ * Draw a line.
+ * FIXME: it is incredibly inefficient to call 'point', especially for long lines
+ * FIXME: clipping maust be moved into this call and drawing to the screen should happen right here
+ * FIXME: line width is not considered
+ */
+void Fl_Android_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1)
+{
+ if (x==x1) {
+ return yxline(x, y, y1);
+ }
+ if (y==y1) {
+ return xyline(x, y, x1);
+ }
+ // Bresenham
+ int w = x1 - x, dx = abs(w);
+ int h = y1 - y, dy = abs(h);
+ int dx1 = sign(w), dy1 = sign(h), dx2, dy2;
+ int min, max;
+ if (dx < dy) {
+ min = dx; max = dy;
+ dx2 = 0;
+ dy2 = dy1;
+ } else {
+ min = dy; max = dx;
+ dx2 = dx1;
+ dy2 = 0;
+ }
+ int num = max/2;
+ for (int i=max+1; i>0; i--) {
+ point_unscaled(x, y);
+ num += min;
+ if (num>=max) {
+ num -= max;
+ x += dx1;
+ y += dy1;
+ } else {
+ x += dx2;
+ y += dy2;
+ }
+ }
+}
+
+/**
+ * Reset the vertex counter to zero.
+ */
+void Fl_Android_Graphics_Driver::begin_vertices()
+{
+ pnVertex = 0;
+ pVertexGapStart = 0;
+}
+
+/**
+ * Add a vertex to the vertex list. Dynamically allocates memory.
+ * @param x, y position of the vertex after matrix transformation
+ * @param gap line and loop call offer to leave a gap in the drawing
+ */
+void Fl_Android_Graphics_Driver::add_vertex(float x, float y, bool gap)
+{
+ if (pnVertex == pNVertex) {
+ pNVertex += 16;
+ pVertex = (Vertex*)::realloc(pVertex, pNVertex*sizeof(Vertex));
+ }
+ pVertex[pnVertex].set(x, y);
+ pVertex[pnVertex].pIsGap = gap;
+ pnVertex++;
+}
+
+/**
+ * Start a list of vertices to draw multiple points.
+ */
+void Fl_Android_Graphics_Driver::begin_points()
+{
+ begin_vertices();
+ Fl_Scalable_Graphics_Driver::begin_points();
+}
+
+/**
+ * Start a list of vertices to draw a polyline.
+ */
+void Fl_Android_Graphics_Driver::begin_line()
+{
+ begin_vertices();
+ Fl_Scalable_Graphics_Driver::begin_line();
+}
+
+/**
+ * Start a list of vertices to draw a line loop.
+ */
+void Fl_Android_Graphics_Driver::begin_loop()
+{
+ begin_vertices();
+ Fl_Scalable_Graphics_Driver::begin_loop();
+}
+
+/**
+ * Start a list of vertices to draw a polygon.
+ */
+void Fl_Android_Graphics_Driver::begin_polygon()
+{
+ begin_vertices();
+ Fl_Scalable_Graphics_Driver::begin_polygon();
+}
+
+/**
+ * Start a list of vertices to draw a complex polygon.
+ */
+void Fl_Android_Graphics_Driver::begin_complex_polygon()
+{
+ begin_vertices();
+ Fl_Scalable_Graphics_Driver::begin_complex_polygon();
+}
+
+/**
+ * Draw all stored vertices as points.
+ */
+void Fl_Android_Graphics_Driver::end_points()
+{
+ for (int i=0; i<pnVertex; ++i) {
+ Vertex &v = pVertex[i];
+ if (!v.pIsGap)
+ point_unscaled(v.pX, v.pY);
+ }
+}
+
+/**
+ * Draw all stored vertices as a polyline.
+ */
+void Fl_Android_Graphics_Driver::end_line()
+{
+ Vertex &v1 = pVertex[0];
+ for (int i=1; i<pnVertex; ++i) {
+ Vertex &v2 = pVertex[i];
+ if (!v1.pIsGap && !v2.pIsGap)
+ line_unscaled(v1.pX, v1.pY, v2.pX, v2.pY);
+ v1 = v2;
+ }
+}
+
+/**
+ * Draw all stored vertices as a polyline loop.
+ */
+void Fl_Android_Graphics_Driver::end_loop()
+{
+ gap();
+ Vertex &v1 = pVertex[0];
+ for (int i=1; i<pnVertex; ++i) {
+ Vertex &v2 = pVertex[i];
+ if (!v1.pIsGap)
+ line_unscaled(v1.pX, v1.pY, v2.pX, v2.pY);
+ v1 = v2;
+ }
+}
+
+/**
+ * Draw all stored vertices as a polygon.
+ * FIXME: these calls are very ineffiecient. Avoid pointer lookup.
+ * FIXME: use the current clipping rect to accelerate rendering
+ * FIXME: unmix float and int
+ */
+void Fl_Android_Graphics_Driver::end_polygon(int begin, int end)
+{
+ if (end - begin < 2) return;
+
+ Vertex *v = pVertex+0;
+ int xMin = v->pX, xMax = xMin, yMin = v->pY, yMax = yMin;
+ for (int i = begin+1; i < end; i++) {
+ v = pVertex+i;
+ if (v->pX < xMin) xMin = v->pX;
+ if (v->pX > xMax) xMax = v->pX;
+ if (v->pY < yMin) yMin = v->pY;
+ if (v->pY > yMax) yMax = v->pY;
+ }
+ xMax++; yMax++;
+
+ int nodes, nodeX[end - begin], pixelX, pixelY, i, j, swap;
+
+ // Loop through the rows of the image.
+ for (pixelY = yMin; pixelY < yMax; pixelY++) {
+ // Build a list of nodes.
+ nodes = 0;
+ j = begin;
+ for (i = begin+1; i < end; i++) {
+ if ( pVertex[i].pY < pixelY && pVertex[j].pY >= pixelY
+ || pVertex[j].pY < pixelY && pVertex[i].pY >= pixelY)
+ {
+ float dy = pVertex[j].pY - pVertex[i].pY;
+ if (fabsf(dy)>.0001) {
+ nodeX[nodes++] = (int)(pVertex[i].pX +
+ (pixelY - pVertex[i].pY) / dy
+ * (pVertex[j].pX - pVertex[i].pX));
+ } else {
+ nodeX[nodes++] = pVertex[i].pX;
+ }
+ }
+ j = i;
+ }
+
+ // Sort the nodes, via a simple “Bubble” sort.
+ i = 0;
+ while (i < nodes - 1) {
+ if (nodeX[i] > nodeX[i + 1]) {
+ swap = nodeX[i];
+ nodeX[i] = nodeX[i + 1];
+ nodeX[i + 1] = swap;
+ if (i) i--;
+ } else {
+ i++;
+ }
+ }
+
+ // Fill the pixels between node pairs.
+ for (i = 0; i < nodes; i += 2) {
+ if (nodeX[i] >= xMax) break;
+ if (nodeX[i + 1] > xMin) {
+ if (nodeX[i] < xMin) nodeX[i] = xMin;
+ if (nodeX[i + 1] > xMax) nodeX[i + 1] = xMax;
+ xyline_unscaled(nodeX[i], pixelY, nodeX[i + 1]);
+ }
+ }
+ }
+
+}
+
+/**
+ * Draw all stored vertices as a polygon.
+ * Mind the gap!
+ */
+void Fl_Android_Graphics_Driver::end_polygon()
+{
+ if (pnVertex==0) return;
+ gap();
+ int start = 0, end = 0;
+ for (int i=0; i<pnVertex; i++) {
+ if (pVertex[i].pIsGap) {
+ end = i+1;
+ end_polygon(start, end);
+ start = end;
+ i++;
+ }
+ }
+}
+
+/**
+ * Draw all stored vertices as a possibly self-intersecting polygon.
+ * FIXME: these calls are very ineffiecient. Avoid pointer lookup.
+ * FIXME: use the current clipping rect to accelerate rendering
+ * FIXME: unmix float and int
+ */
+void Fl_Android_Graphics_Driver::end_complex_polygon()
+{
+ if (pnVertex < 2) return;
+
+ gap(); // adds the first coordinate of this loop and marks it as a gap
+ int begin = 0, end = pnVertex;
+
+ Vertex *v = pVertex+0;
+ int xMin = v->pX, xMax = xMin, yMin = v->pY, yMax = yMin;
+ for (int i = begin+1; i < end; i++) {
+ v = pVertex+i;
+ if (v->pX < xMin) xMin = v->pX;
+ if (v->pX > xMax) xMax = v->pX;
+ if (v->pY < yMin) yMin = v->pY;
+ if (v->pY > yMax) yMax = v->pY;
+ }
+ xMax++; yMax++;
+
+ int nodes, nodeX[end - begin], pixelX, pixelY, i, j, swap;
+
+ // Loop through the rows of the image.
+ for (pixelY = yMin; pixelY < yMax; pixelY++) {
+ // Build a list of nodes.
+ nodes = 0;
+ for (i = begin+1; i < end; i++) {
+ j = i-1;
+ if (pVertex[j].pIsGap)
+ continue;
+ if ( pVertex[i].pY < pixelY && pVertex[j].pY >= pixelY
+ || pVertex[j].pY < pixelY && pVertex[i].pY >= pixelY)
+ {
+ float dy = pVertex[j].pY - pVertex[i].pY;
+ if (fabsf(dy)>.0001) {
+ nodeX[nodes++] = (int)(pVertex[i].pX +
+ (pixelY - pVertex[i].pY) / dy
+ * (pVertex[j].pX - pVertex[i].pX));
+ } else {
+ nodeX[nodes++] = pVertex[i].pX;
+ }
+ }
+ }
+ //Fl_Android_Application::log_e("%d nodes (must be even!)", nodes);
+
+ // Sort the nodes, via a simple “Bubble” sort.
+ i = 0;
+ while (i < nodes - 1) {
+ if (nodeX[i] > nodeX[i + 1]) {
+ swap = nodeX[i];
+ nodeX[i] = nodeX[i + 1];
+ nodeX[i + 1] = swap;
+ if (i) i--;
+ } else {
+ i++;
+ }
+ }
+
+ // Fill the pixels between node pairs.
+ for (i = 0; i < nodes; i += 2) {
+ if (nodeX[i] >= xMax) break;
+ if (nodeX[i + 1] > xMin) {
+ if (nodeX[i] < xMin) nodeX[i] = xMin;
+ if (nodeX[i + 1] > xMax) nodeX[i + 1] = xMax;
+ xyline_unscaled(nodeX[i], pixelY, nodeX[i + 1]);
+ }
+ }
+ }
+}
+
+/**
+ * Add a gap to a polyline drawing
+ */
+void Fl_Android_Graphics_Driver::gap()
+{
+ // drop gaps at the start or gap after gap
+ if (pnVertex==0 || pnVertex==pVertexGapStart)
+ return;
+
+ // create a loop
+ Vertex &v = pVertex[pVertexGapStart];
+ add_vertex(v.pX, v.pY, true);
+ pVertexGapStart = pnVertex;
+}
+
+/**
+ * Add a vertex to the list.
+ * TODO: we should maintain a bounding box for faster clipping.
+ */
+void Fl_Android_Graphics_Driver::transformed_vertex0(float x, float y)
+{
+ add_vertex(x, y);
+}
+
+
+//void Fl_Pico_Graphics_Driver::circle(double x, double y, double r)
+//{
+// begin_loop();
+// double X = r;
+// double Y = 0;
+// fl_vertex(x+X,y+Y);
+//
+// double rx = fabs(transform_dx(r, r));
+// double ry = fabs(transform_dy(r, r));
+//
+// double circ = M_PI*0.5*(rx+ry);
+// int segs = circ * 360 / 1000; // every line is about three pixels long
+// if (segs<16) segs = 16;
+//
+// double A = 2*M_PI;
+// int i = segs;
+//
+// if (i) {
+// double epsilon = A/i; // Arc length for equal-size steps
+// double cos_e = cos(epsilon); // Rotation coefficients
+// double sin_e = sin(epsilon);
+// do {
+// double Xnew = cos_e*X + sin_e*Y;
+// Y = -sin_e*X + cos_e*Y;
+// fl_vertex(x + (X=Xnew), y + Y);
+// } while (--i);
+// }
+// end_loop();
+//}
+
+/**
+ * Draw an arc.
+ * @param xi
+ * @param yi
+ * @param w
+ * @param h
+ * @param a1
+ * @param a2
+ * FIXME: float-to-int interpolation is horrible!
+ */
+void Fl_Android_Graphics_Driver::arc_unscaled(float xi, float yi, float w, float h, double a1, double a2)
+{
+ if (a2<=a1) return;
+
+ double rx = w/2.0;
+ double ry = h/2.0;
+ double x = xi + rx;
+ double y = yi + ry;
+ double circ = M_PI*0.5*(rx+ry);
+ int i, segs = circ * (a2-a1) / 1000; // every line is about three pixels long
+ if (segs<3) segs = 3;
+
+ int px, py;
+ a1 = a1/180*M_PI;
+ a2 = a2/180*M_PI;
+ double step = (a2-a1)/segs;
+
+ int nx = x + cos(a1)*rx;
+ int ny = y - sin(a1)*ry;
+ for (i=segs; i>0; i--) {
+ a1+=step;
+ px = nx; py = ny;
+ nx = x + cos(a1)*rx;
+ ny = y - sin(a1)*ry;
+ line_unscaled(px, py, nx, ny);
+ }
+}
+
+void Fl_Android_Graphics_Driver::pie_unscaled(float xi, float yi, float w, float h, double b1, double b2)
+{
+ Fl_Color c = fl_color();
+ fl_color(FL_RED);
+ double a1 = b1/180*M_PI;
+ double a2 = b2/180*M_PI;
+ double rx = w/2.0;
+ double ry = h/2.0;
+ double x = xi + rx;
+ double y = yi + ry;
+ double yMin = y - sin(a1), yMax = y - sin(a2);
+ if (yMin>yMax) { double s = yMin; yMin = yMax; yMax = s; }
+ Fl_Android_Application::log_e("------ PI");
+ for (double i=y-ry; i<=y+ry; i++) {
+ double a = asin((i-y)/ry);
+ double aR = a; if (aR<0.0) aR+=2*M_PI;
+ double aL = M_PI-a;
+ Fl_Android_Application::log_e("%g %g", aL, aR);
+#if 0
+ if (aL>=a1 && aL<=a2)
+ xyline_unscaled(x-cos(a)*rx, i, x);
+
+ if (aR>=a1 && aR<=a2)
+ xyline_unscaled(x, i, x+cos(a)*rx);
+#else
+ xyline_unscaled(x-cos(a)*rx, i, x+cos(a)*rx);
+#endif
+ //xyline_unscaled(sin(a)*rx, i, y);
+ }
+ fl_color(FL_GREEN);
+ line_unscaled(x, y, x+cos(0.5*M_PI)*rx, y+sin(0.5*M_PI)*ry);
+ fl_color(c);
+}
+
+
#if 0
diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.cxx b/src/drivers/Android/Fl_Android_Graphics_Font.cxx
index 5a06a0ad7..da8f9ddf4 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Font.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Font.cxx
@@ -517,11 +517,11 @@ void Fl_Android_Graphics_Driver::draw_unscaled(const char* str, int n, int x, in
if (str) {
int dx, dy, w, h;
text_extents_unscaled(str, n, dx, dy, w, h);
- pClippingRegion.print("<---- clip text to this");
- Fl_Rect_Region(x+dx, y+dy, w, h).print(str);
+ //pClippingRegion.print("<---- clip text to this");
+ //Fl_Rect_Region(x+dx, y+dy, w, h).print(str);
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x+dx, y+dy, w, h))) {
Fl_Rect_Region &r = it->clipped_rect();
- r.print("Clip");
+ //r.print("Clip");
const char *e = str + n;
for (int i = 0; i < n;) {
int incr = 1;