... |
... |
@@ -72,6 +72,13 @@ |
72
|
72
|
#define MD5_Update FT_MD5_Update
|
73
|
73
|
#define MD5_Final FT_MD5_Final
|
74
|
74
|
|
|
75
|
+#define PIXEL_BITS 8
|
|
76
|
+
|
|
77
|
+#define ONE_PIXEL ( 1 << PIXEL_BITS )
|
|
78
|
+#define TRUNC( x ) (int)( ( x ) >> PIXEL_BITS )
|
|
79
|
+
|
|
80
|
+#define UPSCALE( x ) ( ( x ) * ( ONE_PIXEL >> 6 ) )
|
|
81
|
+#define DOWNSCALE( x ) ( ( x ) >> ( PIXEL_BITS - 6 ) )
|
75
|
82
|
#undef HAVE_OPENSSL
|
76
|
83
|
|
77
|
84
|
#include "md5.c"
|
... |
... |
@@ -2543,6 +2550,98 @@ |
2543
|
2550
|
|
2544
|
2551
|
|
2545
|
2552
|
|
|
2553
|
+static FT_Vector
|
|
2554
|
+Lerp( float T, FT_Vector P0, FT_Vector P1 )
|
|
2555
|
+{
|
|
2556
|
+ FT_Vector p;
|
|
2557
|
+ p.x = P0.x + T * ( P1.x - P0.x );
|
|
2558
|
+ p.y = P0.y + T * ( P1.y - P0.y );
|
|
2559
|
+ return p;
|
|
2560
|
+}
|
|
2561
|
+
|
|
2562
|
+int conic_to2(FT_GlyphSlot* slot, FT_Vector *control, FT_Vector *from, FT_Vector *to, FT_PreLine *ptr)
|
|
2563
|
+{
|
|
2564
|
+ /*
|
|
2565
|
+ Calculate devsq as the square of four times the
|
|
2566
|
+ distance from the control point to the midpoint of the curve.
|
|
2567
|
+ This is the place at which the curve is furthest from the
|
|
2568
|
+ line joining the control points.
|
|
2569
|
+
|
|
2570
|
+ 4 x point on curve = p0 + 2p1 + p2
|
|
2571
|
+ 4 x midpoint = 4p1
|
|
2572
|
+
|
|
2573
|
+ The division by four is omitted to save time.
|
|
2574
|
+ */
|
|
2575
|
+ //FT_PreLine ptr = (*slot)->prelines;
|
|
2576
|
+ if((*slot)->glyph_index == 38)
|
|
2577
|
+ printf("conic from %d, %d to %d, %d via %d, %d\n", from->x, from->y, to->x, to->y, control->x, control->y);
|
|
2578
|
+ FT_Vector aP0 = { from->x , from->y};
|
|
2579
|
+ FT_Vector aP1 = { control->x, control->y };
|
|
2580
|
+ FT_Vector aP2 = { to->x, to->y };
|
|
2581
|
+
|
|
2582
|
+ float devx = aP0.x - aP1.x - aP1.x + aP2.x;
|
|
2583
|
+ float devy = aP0.y - aP1.y - aP1.y + aP2.y;
|
|
2584
|
+ float devsq = devx * devx + devy * devy;
|
|
2585
|
+
|
|
2586
|
+ if ( devsq < 0.333f )
|
|
2587
|
+ {
|
|
2588
|
+ //dense_line_to( &aP2, worker );
|
|
2589
|
+ FT_PreLine pl3 = malloc(sizeof(FT_PreLineRec));
|
|
2590
|
+ pl3->x1 = (*ptr)->x2;
|
|
2591
|
+ pl3->y1 = (*ptr)->y2;
|
|
2592
|
+ pl3->x2 = aP2.x;
|
|
2593
|
+ pl3->y2 = aP2.y;
|
|
2594
|
+ pl3->next = NULL;
|
|
2595
|
+ pl3->ismove = 0;
|
|
2596
|
+ (*ptr)->next = pl3;
|
|
2597
|
+ *ptr = (*ptr)->next;
|
|
2598
|
+ return;
|
|
2599
|
+ }
|
|
2600
|
+
|
|
2601
|
+ /*
|
|
2602
|
+ According to Raph Levien, the reason for the subdivision by n (instead of
|
|
2603
|
+ recursive division by the Casteljau system) is that "I expect the flatness
|
|
2604
|
+ computation to be semi-expensive (it's done once rather than on each potential
|
|
2605
|
+ subdivision) and also because you'll often get fewer subdivisions. Taking a
|
|
2606
|
+ circular arc as a simplifying assumption, where I get n, a recursive approach
|
|
2607
|
+ would get 2^ceil(lg n), which, if I haven't made any horrible mistakes, is
|
|
2608
|
+ expected to be 33% more in the limit".
|
|
2609
|
+ */
|
|
2610
|
+
|
|
2611
|
+ const float tol = 3.0f;
|
|
2612
|
+ int n = (int)floor( sqrt( sqrt( tol * devsq ) ) )/8;
|
|
2613
|
+ FT_Vector p = aP0;
|
|
2614
|
+ float nrecip = 1.0f / ( n + 1.0f );
|
|
2615
|
+ float t = 0.0f;
|
|
2616
|
+ for ( int i = 0; i < n; i++ )
|
|
2617
|
+ {
|
|
2618
|
+ t += nrecip;
|
|
2619
|
+ FT_Vector next = Lerp( t, Lerp( t, aP0, aP1 ), Lerp( t, aP1, aP2 ) );
|
|
2620
|
+ //dense_line_to(&next, worker );
|
|
2621
|
+ FT_PreLine pl4 = malloc(sizeof(FT_PreLineRec));
|
|
2622
|
+ pl4->x1 = (*ptr)->x2;
|
|
2623
|
+ pl4->y1 = (*ptr)->y2;
|
|
2624
|
+ pl4->x2 = next.x;
|
|
2625
|
+ pl4->y2 = next.y;
|
|
2626
|
+ pl4->next = NULL;
|
|
2627
|
+ pl4->ismove = 0;
|
|
2628
|
+ (*ptr)->next = pl4;
|
|
2629
|
+ *ptr = (*ptr)->next;
|
|
2630
|
+ p = next;
|
|
2631
|
+ }
|
|
2632
|
+
|
|
2633
|
+ //dense_line_to( &aP2, worker );
|
|
2634
|
+ FT_PreLine pl5 = malloc(sizeof(FT_PreLineRec));
|
|
2635
|
+ pl5->x1 = (*ptr)->x2;
|
|
2636
|
+ pl5->y1 = (*ptr)->y2;
|
|
2637
|
+ pl5->x2 = aP2.x;
|
|
2638
|
+ pl5->y2 = aP2.y;
|
|
2639
|
+ pl5->next = NULL;
|
|
2640
|
+ pl5->ismove = 0;
|
|
2641
|
+ (*ptr)->next = pl5;
|
|
2642
|
+ *ptr = (*ptr)->next;
|
|
2643
|
+
|
|
2644
|
+}
|
2546
|
2645
|
|
2547
|
2646
|
|
2548
|
2647
|
static FT_Error ft_decompose_outline(FT_GlyphSlot* slot){
|
... |
... |
@@ -2688,6 +2787,76 @@ |
2688
|
2787
|
ptr = ptr->next;
|
2689
|
2788
|
continue;
|
2690
|
2789
|
}
|
|
2790
|
+
|
|
2791
|
+ case FT_CURVE_TAG_CONIC: /* consume conic arcs */
|
|
2792
|
+ // v_control.x = SCALED( point->x );
|
|
2793
|
+ // v_control.y = SCALED( point->y );
|
|
2794
|
+ v_control.x = point->x ;
|
|
2795
|
+ v_control.y = point->y ;
|
|
2796
|
+
|
|
2797
|
+ Do_Conic:
|
|
2798
|
+ if ( point < limit )
|
|
2799
|
+ {
|
|
2800
|
+ FT_Vector vec;
|
|
2801
|
+ FT_Vector v_middle;
|
|
2802
|
+
|
|
2803
|
+
|
|
2804
|
+ point++;
|
|
2805
|
+ tags++;
|
|
2806
|
+ tag = FT_CURVE_TAG( tags[0] );
|
|
2807
|
+
|
|
2808
|
+ // vec.x = SCALED( point->x );
|
|
2809
|
+ // vec.y = SCALED( point->y );
|
|
2810
|
+ vec.x = point->x;
|
|
2811
|
+ vec.y = point->y;
|
|
2812
|
+
|
|
2813
|
+ if ( tag == FT_CURVE_TAG_ON )
|
|
2814
|
+ {
|
|
2815
|
+ FT_TRACE5(( " conic to (%.2f, %.2f)"
|
|
2816
|
+ " with control (%.2f, %.2f)\n",
|
|
2817
|
+ (double)vec.x / 64,
|
|
2818
|
+ (double)vec.y / 64,
|
|
2819
|
+ (double)v_control.x / 64,
|
|
2820
|
+ (double)v_control.y / 64 ));
|
|
2821
|
+ FT_Vector vex0 = {ptr->x2, ptr->y2};
|
|
2822
|
+ error = conic_to2(slot, &v_control, &vex0,&vec , &ptr);
|
|
2823
|
+ // if ( error )
|
|
2824
|
+ // goto Exit;
|
|
2825
|
+ continue;
|
|
2826
|
+ }
|
|
2827
|
+
|
|
2828
|
+ if ( tag != FT_CURVE_TAG_CONIC )
|
|
2829
|
+ {
|
|
2830
|
+ FT_TRACE5( ( "Invalid Outline" ) );
|
|
2831
|
+ break;
|
|
2832
|
+ }
|
|
2833
|
+ v_middle.x = ( v_control.x + vec.x ) / 2;
|
|
2834
|
+ v_middle.y = ( v_control.y + vec.y ) / 2;
|
|
2835
|
+
|
|
2836
|
+ FT_TRACE5(( " conic to (%.2f, %.2f)"
|
|
2837
|
+ " with control (%.2f, %.2f)\n",
|
|
2838
|
+ (double)v_middle.x / 64,
|
|
2839
|
+ (double)v_middle.y / 64,
|
|
2840
|
+ (double)v_control.x / 64,
|
|
2841
|
+ (double)v_control.y / 64 ));
|
|
2842
|
+ FT_Vector vex = {ptr->x2, ptr->y2};
|
|
2843
|
+ error = conic_to2(slot, &v_control, &vex,&v_middle, &ptr);
|
|
2844
|
+ // if ( error )
|
|
2845
|
+ // goto Exit;
|
|
2846
|
+
|
|
2847
|
+ v_control = vec;
|
|
2848
|
+ goto Do_Conic;
|
|
2849
|
+ }
|
|
2850
|
+
|
|
2851
|
+ FT_TRACE5(( " conic to (%.2f, %.2f)"
|
|
2852
|
+ " with control (%.2f, %.2f)\n",
|
|
2853
|
+ (double)v_start.x / 64,
|
|
2854
|
+ (double)v_start.y / 64,
|
|
2855
|
+ (double)v_control.x / 64,
|
|
2856
|
+ (double)v_control.y / 64 ));
|
|
2857
|
+ FT_Vector vex2 = {ptr->x2, ptr->y2};
|
|
2858
|
+ error = conic_to2( slot, &v_control, &vex2, &v_start, &ptr );
|
|
2859
|
+ //goto Close;
|
2691
|
2860
|
|
2692
|
2861
|
}
|
2693
|
2862
|
}
|