Bool gf_svg_attributes_equal()

in src/scenegraph/svg_attributes.c [4931:5303]


Bool gf_svg_attributes_equal(GF_FieldInfo *f1, GF_FieldInfo *f2)
{
	u32 v1, v2;
	if (f1->fieldType!=f2->fieldType) return 0;
	if (f1->far_ptr && !f2->far_ptr) return 0;
	if (f2->far_ptr && !f1->far_ptr) return 0;
	if (!f1->far_ptr) return 1;
	v1 = *(u8 *)f1->far_ptr;
	v2 = *(u8 *)f2->far_ptr;

	switch (f1->fieldType) {
	case SVG_Boolean_datatype:
	case SVG_FillRule_datatype:
	case SVG_StrokeLineJoin_datatype:
	case SVG_StrokeLineCap_datatype:
	case SVG_FontStyle_datatype:
	case SVG_FontWeight_datatype:
	case SVG_FontVariant_datatype:
	case SVG_TextAnchor_datatype:
	case SVG_Display_datatype:
	case SVG_Visibility_datatype:
	case SVG_GradientUnit_datatype:
	case SVG_PreserveAspectRatio_datatype:
	case XML_Space_datatype:
	case XMLEV_Propagate_datatype:
	case XMLEV_DefaultAction_datatype:
	case XMLEV_Phase_datatype:
	case SMIL_SyncBehavior_datatype:
	case SMIL_AttributeType_datatype:
	case SMIL_CalcMode_datatype:
	case SMIL_Additive_datatype:
	case SMIL_Accumulate_datatype:
	case SMIL_Restart_datatype:
	case SMIL_Fill_datatype:
	case SVG_Overflow_datatype:
	case SVG_ZoomAndPan_datatype:
	case SVG_DisplayAlign_datatype:
	case SVG_TextAlign_datatype:
	case SVG_PointerEvents_datatype:
	case SVG_RenderingHint_datatype:
	case SVG_VectorEffect_datatype:
	case SVG_PlaybackOrder_datatype:
	case SVG_TimelineBegin_datatype:
	case SVG_FocusHighlight_datatype:
	case SVG_TransformType_datatype:
	case SVG_Overlay_datatype:
	case SVG_TransformBehavior_datatype:
	case SVG_SpreadMethod_datatype:
	case SVG_InitialVisibility_datatype:
	case LASeR_Choice_datatype:
		return (v1==v2) ? 1 : 0;
	case SVG_Color_datatype:
		return svg_colors_equal((SVG_Color *)f1->far_ptr, (SVG_Color *)f2->far_ptr);
	case SMIL_SyncTolerance_datatype:
	{
		SMIL_SyncTolerance *st1 = (SMIL_SyncTolerance*)f1->far_ptr;
		SMIL_SyncTolerance *st2 = (SMIL_SyncTolerance*)f2->far_ptr;
		if (st1->type!=st2->type) return 0;
		if ((st1->type==SMIL_SYNCTOLERANCE_VALUE) && (st1->value!=st2->value)) return 0;
		return 1;
	}

	case SVG_Paint_datatype:
	{
		SVG_Paint *p1 = (SVG_Paint *)f1->far_ptr;
		SVG_Paint *p2 = (SVG_Paint *)f2->far_ptr;
		if (p1->type != p2->type) return 0;
		if (p1->type==SVG_PAINT_COLOR) return svg_colors_equal(&p1->color, &p2->color);
		else if (p1->type==SVG_PAINT_URI) return svg_iris_equal(&p1->iri, &p2->iri);
		return 1;
	}
	break;

	case SVG_FontSize_datatype:
	case SVG_Length_datatype:
	case SVG_Coordinate_datatype:
	case SVG_Rotate_datatype:
	case SVG_Number_datatype:
		return svg_numbers_equal((SVG_Number *)f1->far_ptr, (SVG_Number *)f2->far_ptr);
	case XMLRI_datatype:
		return svg_iris_equal((XMLRI*)f1->far_ptr, (XMLRI*)f2->far_ptr);
	case XMLRI_List_datatype:
	{
		GF_List *l1 = *(GF_List **)f1->far_ptr;
		GF_List *l2 = *(GF_List **)f2->far_ptr;
		u32 i, count = gf_list_count(l1);
		if (gf_list_count(l2)!=count) return 0;
		for (i=0; i<count; i++) {
			if (!svg_iris_equal((XMLRI*)gf_list_get(l1, i), (XMLRI*)gf_list_get(l2, i) )) return 0;
		}
		return 1;
	}

	case SVG_PathData_datatype:
	{
		SVG_PathData *d1 = (SVG_PathData *)f1->far_ptr;
		SVG_PathData *d2 = (SVG_PathData *)f2->far_ptr;
		u32 i;
		/*FIXME - be less lazy..*/
#if USE_GF_PATH
		if (d1->n_points != d2->n_points) return 0;
		if (d1->n_contours != d2->n_contours) return 0;
		for (i=0; i<d1->n_points; i++) {
			if (d1->points[i].x != d2->points[i].x) return 0;
			if (d1->points[i].y != d2->points[i].y) return 0;
		}
		for (i=0; i<d1->n_points; i++) {
			if (d1->tags[i] != d2->tags[i]) return 0;
		}
		for (i=0; i<d1->n_contours; i++) {
			if (d1->contours[i] != d2->contours[i]) return 0;
		}
		return 1;
#else
		if (!gf_list_count(d1->commands) && !gf_list_count(d2->commands)) return 1;
#endif
		return 0;
	}
	case SVG_Points_datatype:
	{
		GF_List *l1 = *(GF_List **) f1->far_ptr;
		GF_List *l2 = *(GF_List **) f2->far_ptr;
		u32 i = 0;
		u32 count = gf_list_count(l1);
		if (gf_list_count(l2)!=count) return 0;
		for (i=0; i<count; i++) {
			SVG_Point *p1 = (SVG_Point *)gf_list_get(l1, i);
			SVG_Point *p2 = (SVG_Point *)gf_list_get(l2, i);
			if (p1->x != p2->x) return 0;
			if (p1->y != p2->y) return 0;
		}
		return 1;
	}
	case SMIL_KeyTimes_datatype:
	case SMIL_KeyPoints_datatype:
	case SMIL_KeySplines_datatype:
	{
		GF_List *l1 = *(GF_List **) f1->far_ptr;
		GF_List *l2 = *(GF_List **) f2->far_ptr;
		u32 i = 0;
		u32 count = gf_list_count(l1);
		if (gf_list_count(l2)!=count) return 0;
		for (i=0; i<count; i++) {
			Fixed *p1 = (Fixed *)gf_list_get(l1, i);
			Fixed *p2 = (Fixed *)gf_list_get(l2, i);
			if (*p1 != *p2) return 0;
		}
		return 1;
	}
	case SVG_Coordinates_datatype:
	{
		GF_List *l1 = *(GF_List **) f1->far_ptr;
		GF_List *l2 = *(GF_List **) f2->far_ptr;
		u32 i = 0;
		u32 count = gf_list_count(l1);
		if (gf_list_count(l2) != count) return 0;
		for (i=0; i<count; i++) {
			SVG_Coordinate *p1 = (SVG_Coordinate *)gf_list_get(l1, i);
			SVG_Coordinate *p2 = (SVG_Coordinate *)gf_list_get(l2, i);
			if (!svg_numbers_equal(p1, p2)) return 0;
		}
		return 1;
	}
	case SVG_ViewBox_datatype:
	{
		SVG_ViewBox *v1 = (SVG_ViewBox *)f1->far_ptr;
		SVG_ViewBox *v2 = (SVG_ViewBox *)f2->far_ptr;
		return svg_viewbox_equal(v1, v2);
	}
	case SVG_StrokeDashArray_datatype:
	{
		SVG_StrokeDashArray *p1 = (SVG_StrokeDashArray *)f1->far_ptr;
		SVG_StrokeDashArray *p2 = (SVG_StrokeDashArray *)f2->far_ptr;
		if (p1->type!=p2->type) return 0;
		if (p1->type==SVG_STROKEDASHARRAY_ARRAY) {
			u32 i = 0;
			if (p1->array.count != p2->array.count) return 0;
			for (i=0; i<p1->array.count; i++) {
				if (p1->array.units[i] != p2->array.units[i]) return 0;
				if (p1->array.vals[i] != p2->array.vals[i]) return 0;
			}
		}
		return 1;
	}
	case SVG_FontFamily_datatype:
	{
		SVG_FontFamily *ff1 = (SVG_FontFamily *)f1->far_ptr;
		SVG_FontFamily *ff2 = (SVG_FontFamily *)f2->far_ptr;
		if (ff1->type!=ff2->type) return 0;
		if (ff1->type==SVG_FONTFAMILY_INHERIT) return 1;
		return (ff1->value && ff2->value && !strcmp(ff1->value, ff2->value)) ? 1 : 0;
	}

	case SVG_Clock_datatype:
		return (* (SVG_Clock *)f1->far_ptr == * (SVG_Clock *)f2->far_ptr) ? 1 : 0;

	/* required for animateMotion */
	case SVG_Motion_datatype:
		return svg_matrices_equal((GF_Matrix2D*)f1->far_ptr, (GF_Matrix2D*)f2->far_ptr);

	case SVG_Transform_datatype:
	{
		SVG_Transform *t1 = (SVG_Transform *)f1->far_ptr;
		SVG_Transform *t2 = (SVG_Transform *)f2->far_ptr;
		if (t1->is_ref == t2->is_ref)
			return svg_matrices_equal(&t1->mat, &t2->mat);
		else
			return 0;
	}

	case SVG_Transform_Translate_datatype:
	case SVG_Transform_Scale_datatype:
	{
		SVG_Point *p1 = (SVG_Point *)f1->far_ptr;
		SVG_Point *p2 = (SVG_Point *)f2->far_ptr;
		if (p1->x != p2->x) return 0;
		if (p1->y != p2->y) return 0;
		return 1;
	}

	case SVG_Transform_SkewX_datatype:
	case SVG_Transform_SkewY_datatype:
	{
		Fixed *p1 = (Fixed *)f1->far_ptr;
		Fixed *p2 = (Fixed *)f2->far_ptr;
		return (*p1 == *p2);
	}

	case SVG_Transform_Rotate_datatype:
	{
		SVG_Point_Angle *p1 = (SVG_Point_Angle *)f1->far_ptr;
		SVG_Point_Angle *p2 = (SVG_Point_Angle *)f2->far_ptr;
		if (p1->x != p2->x) return 0;
		if (p1->y != p2->y) return 0;
		if (p1->angle != p2->angle) return 0;
		return 1;
	}


	case SVG_ID_datatype:
	case SVG_LanguageID_datatype:
	case SVG_GradientOffset_datatype:
	case DOM_String_datatype:
	case SVG_ContentType_datatype:
	{
		char *str1 = *(SVG_String *)f1->far_ptr;
		char *str2 = *(SVG_String *)f2->far_ptr;
		if (!str1 && !str2) return 1;
		return (str1 && str2 && !strcmp(str1, str2)) ? 1 : 0;
	}

	case SVG_Focus_datatype:
	{
		SVG_Focus *foc1 = (SVG_Focus *) f1->far_ptr;
		SVG_Focus *foc2 = (SVG_Focus *)f2->far_ptr;
		if (foc1->type!=foc2->type) return 0;
		if (foc1->type != SVG_FOCUS_IRI) return 1;
		return (foc1->target.string && foc2->target.string && !strcmp(foc1->target.string, foc2->target.string)) ? 1 : 0;
	}
	break;

	case DOM_StringList_datatype:
	{
		GF_List *l1 = *(GF_List **) f1->far_ptr;
		GF_List *l2 = *(GF_List **) f2->far_ptr;
		u32 i = 0;
		u32 count = gf_list_count(l1);
		if (gf_list_count(l2) != count) return 0;
		for (i=0; i<count; i++) {
			char *p1 = (char *)gf_list_get(l1, i);
			char *p2 = (char *)gf_list_get(l2, i);
			if (strcmp(p1, p2)) return 0;
		}
		return 1;
	}
	case SVG_Numbers_datatype:
	{
		GF_List *l1 = *(GF_List **) f1->far_ptr;
		GF_List *l2 = *(GF_List **) f2->far_ptr;
		u32 i = 0;
		u32 count = gf_list_count(l1);
		if (gf_list_count(l2) != count) return 0;
		for (i=0; i<count; i++) {
			SVG_Number *p1 = (SVG_Number *)gf_list_get(l1, i);
			SVG_Number *p2 = (SVG_Number *)gf_list_get(l2, i);
			if (!svg_numbers_equal(p1, p2)) return 0;
		}
		return 1;
	}
	case SMIL_Times_datatype:
	{
		GF_List *l1 = *(GF_List **) f1->far_ptr;
		GF_List *l2 = *(GF_List **) f2->far_ptr;
		u32 i = 0;
		u32 count = gf_list_count(l1);
		if (gf_list_count(l2) != count) return 0;
		for (i=0; i<count; i++) {
			SMIL_Time *p1 = (SMIL_Time *)gf_list_get(l1, i);
			SMIL_Time *p2 = (SMIL_Time *)gf_list_get(l2, i);
			if (p1->type != p2->type) return 0;
			if (p1->clock != p2->clock) return 0;
			if (p1->type==GF_SMIL_TIME_EVENT) {
				if (p1->event.type != p2->event.type) return 0;
				if (p1->event.parameter != p2->event.parameter) return 0;
			}
		}
		return 1;
	}
	case SMIL_Duration_datatype:
	{
		SMIL_Duration *d1 = (SMIL_Duration *)f1->far_ptr;
		SMIL_Duration *d2 = (SMIL_Duration *)f2->far_ptr;
		if (d1->type != d2->type) return 0;
		if (d1->clock_value != d2->clock_value) return 0;
		return 1;
	}
	case SMIL_RepeatCount_datatype:
	{
		SMIL_RepeatCount *d1 = (SMIL_RepeatCount *)f1->far_ptr;
		SMIL_RepeatCount *d2 = (SMIL_RepeatCount *)f2->far_ptr;
		if (d1->type != d2->type) return 0;
		if (d1->count != d2->count) return 0;
		return 1;
	}

	case SMIL_AttributeName_datatype:
	{
		SMIL_AttributeName *att1 = (SMIL_AttributeName *) f1->far_ptr;
		SMIL_AttributeName *att2 = (SMIL_AttributeName *) f2->far_ptr;
		/*TODO check me...*/
		if (att2->field_ptr == att1->field_ptr) return 1;
		return 0;
	}

	case SMIL_AnimateValue_datatype:
	{
		SMIL_AnimateValue *av1 = (SMIL_AnimateValue*)f1->far_ptr;
		SMIL_AnimateValue *av2 = (SMIL_AnimateValue*)f2->far_ptr;
		if (av1->value != av2->value) return 0;
		return 1;
	}
	break;

	case SMIL_AnimateValues_datatype:
	{
		u32 count;
		SMIL_AnimateValues *av1 = (SMIL_AnimateValues*)f1->far_ptr;
		SMIL_AnimateValues *av2 = (SMIL_AnimateValues*)f2->far_ptr;
		if (av1->type != av2->type) return 0;
		if ( (count = gf_list_count(av1->values) ) != gf_list_count(av1->values)) return 0;
		return count ? 0 : 1;
	}
	case XMLEV_Event_datatype:
	{
		XMLEV_Event *d1 = (XMLEV_Event *)f1->far_ptr;
		XMLEV_Event *d2 = (XMLEV_Event *)f2->far_ptr;
		if (d1->type != d2->type) return 0;
		if (d1->parameter != d2->parameter) return 0;
		return 1;
	}
	case LASeR_Size_datatype:
	{
		LASeR_Size *sz1 = (LASeR_Size *)f1->far_ptr;
		LASeR_Size *sz2 = (LASeR_Size *)f2->far_ptr;
		if (sz1->width != sz2->width) return 0;
		if (sz1->height != sz2->height) return 0;
		return 1;
	}
	default:
		GF_LOG(GF_LOG_WARNING, GF_LOG_INTERACT, ("[SVG Attributes] comparaison for field %s of type %s not supported\n", f1->name, gf_svg_attribute_type_to_string(f1->fieldType)));
		return 0;
	}
}