@@ -712,3 +712,106 @@ void MCGPlatformFinalize(void)
712712}
713713
714714// //////////////////////////////////////////////////////////////////////////////
715+
716+ static void __expand_bounds (RECT& r, POINT& p)
717+ {
718+ if (p . x < r . left)
719+ r . left = p . x;
720+ if (p . x > r . right)
721+ r . right = p . x;
722+ if (p . y < r . top)
723+ r . top = p . y;
724+ if (p . y > r . bottom)
725+ r . bottom = p . y;
726+ }
727+
728+ bool MCGContextMeasurePlatformTextImageBounds (MCGContextRef self, const unichar_t *p_text, uindex_t p_length, const MCGFont& p_font, const MCGAffineTransform& p_transform, MCGRectangle &r_bounds)
729+ {
730+ bool t_success;
731+ t_success = true ;
732+
733+ if (t_success)
734+ t_success = SelectObject (s_measure_dc, p_font . fid) != NULL ;
735+
736+ if (t_success)
737+ {
738+ XFORM t_xform;
739+ t_xform . eM11 = p_transform . a;
740+ t_xform . eM12 = 0 ;
741+ t_xform . eM21 = 0 ;
742+ t_xform . eM22 = p_transform . d;
743+ t_xform . eDx = 0 ;
744+ t_xform . eDy = 0 ;
745+ t_success = SetWorldTransform (s_measure_dc, &t_xform);
746+ }
747+
748+ if (t_success)
749+ {
750+ BeginPath (s_measure_dc);
751+ SetBkMode (s_measure_dc, TRANSPARENT);
752+ SetTextAlign (s_measure_dc, TA_BASELINE);
753+ if (p_font . fixed_advance == 0 )
754+ TextOutW (s_measure_dc, 0 , 0 , p_text, p_length / 2 );
755+ else
756+ {
757+ // MW-2013-12-05: [[ Bug 11535 ]] If fixed advance, then make the advance
758+ // width of each char fixed_advance.
759+ INT *t_dxs;
760+ /* UNCHECKED */ MCMemoryNewArray (p_length / 2 , t_dxs);
761+ for (uindex_t i = 0 ; i < p_length / 2 ; i++)
762+ t_dxs[i] = p_font . fixed_advance;
763+ ExtTextOutW (s_measure_dc, 0 , 0 , 0 , NULL , p_text, p_length / 2 , t_dxs);
764+ MCMemoryDeleteArray (t_dxs);
765+ }
766+ EndPath (s_measure_dc);
767+
768+ int t_count;
769+ t_count = GetPath (s_measure_dc, NULL , NULL , 0 );
770+
771+ RECT t_bounds;
772+ t_bounds . left = INT_MAX;
773+ t_bounds . top = INT_MAX;
774+ t_bounds . right = INT_MIN;
775+ t_bounds . bottom = INT_MIN;
776+
777+ POINT *t_points;
778+ BYTE *t_types;
779+ t_points = new POINT[t_count];
780+ t_types = new BYTE[t_count];
781+ GetPath (s_measure_dc, t_points, t_types, t_count);
782+
783+ for (int i = 0 ; i < t_count;)
784+ {
785+ switch (t_types[i] & ~PT_CLOSEFIGURE)
786+ {
787+ case PT_MOVETO:
788+ __expand_bounds (t_bounds, t_points[i]);
789+ i += 1 ;
790+ break ;
791+
792+ case PT_LINETO:
793+ __expand_bounds (t_bounds, t_points[i]);
794+ i += 1 ;
795+ break ;
796+
797+ case PT_BEZIERTO:
798+ __expand_bounds (t_bounds, t_points[i + 0 ]);
799+ __expand_bounds (t_bounds, t_points[i + 1 ]);
800+ __expand_bounds (t_bounds, t_points[i + 2 ]);
801+ i += 3 ;
802+ break ;
803+ }
804+ }
805+
806+ delete t_points;
807+ delete t_types;
808+
809+ r_bounds = MCGRectangleMake (t_bounds.left , t_bounds.top , t_bounds.right - t_bounds.left , t_bounds.bottom - t_bounds.top );
810+ }
811+
812+ AbortPath (s_measure_dc);
813+
814+ return true ;
815+ }
816+
817+ // //////////////////////////////////////////////////////////////////////////////
0 commit comments