package d2svg

import (
	
	

	
	
	
	
	
)

// markdownRenderer owns the shared measurement state used while rendering a
// diagram. LayoutMarkdown returns both the dimensions used by graph layout and
// the primitives painted here, so native SVG output cannot drift onto a
// separate browser layout path.
type markdownRenderer struct {
	ruler          *textmeasure.Ruler
	rulerErr       error
	fontFamily     *d2fonts.FontFamily
	monoFontFamily *d2fonts.FontFamily
	inlineTheme    *d2themes.Theme
	corpus         strings.Builder
}

func newMarkdownRenderer(,  *d2fonts.FontFamily,  *d2themes.Theme) *markdownRenderer {
	if  == nil || * == "" {
		 := d2fonts.SourceSansPro
		 = &
	}
	if  == nil || * == "" {
		 := d2fonts.SourceCodePro
		 = &
	}
	return &markdownRenderer{
		fontFamily:     ,
		monoFontFamily: ,
		inlineTheme:    ,
	}
}

func ( *markdownRenderer) (,  string,  int) (*textmeasure.MarkdownLayout, error) {
	 := .fontFamily
	if strings.EqualFold(, "mono") {
		 = .monoFontFamily
	} else if  != "" && !strings.EqualFold(, "default") {
		if  := fontToFamily(strings.ToLower());  != nil {
			 = 
		}
	}

	return .layoutWithFont(, , .monoFontFamily, )
}

func ( *markdownRenderer) ( string, ,  *d2fonts.FontFamily,  int) (*textmeasure.MarkdownLayout, error) {
	if .ruler == nil && .rulerErr == nil {
		.ruler, .rulerErr = textmeasure.NewRuler()
	}
	if .rulerErr != nil {
		return nil, .rulerErr
	}
	,  := textmeasure.LayoutMarkdown(, .ruler, , , )
	if  != nil {
		return nil, 
	}
	.corpus.WriteString(.Corpus)
	return , nil
}

func ( *markdownRenderer) (
	 *textmeasure.MarkdownLayout,
	,  float64,
	,  int,
	,  string,
	 bool,
	 bool,
) string {
	var  strings.Builder
	fmt.Fprintf(&, `<svg x="%s" y="%s" width="%d" height="%d" viewBox="0 0 %d %d" overflow="hidden">`,
		svg.FormatFloat(), svg.FormatFloat(), , , , ,
	)

	if  != "" &&  != color.None &&  != "transparent" {
		 := d2themes.NewThemableElement("rect", .inlineTheme)
		.Width = float64()
		.Height = float64()
		.Fill = 
		.WriteString(.Render())
	}

	 := map[textmeasure.MarkdownColorRole]textmeasure.MarkdownSVGPaint{
		textmeasure.MarkdownColorForeground:       .fillPaint(),
		textmeasure.MarkdownColorForegroundStroke: .strokePaint(),
		textmeasure.MarkdownColorMuted:            .fillPaint(color.N2),
		textmeasure.MarkdownColorMutedStroke:      .strokePaint(color.N2),
		textmeasure.MarkdownColorAccent:           .fillPaint(color.B2),
		textmeasure.MarkdownColorBorder:           .fillPaint(color.B1),
		textmeasure.MarkdownColorBorderMuted:      .fillPaint(color.B2),
		textmeasure.MarkdownColorCanvas:           .fillPaint(color.N7),
		textmeasure.MarkdownColorCanvasSubtle:     .fillPaint(color.N6),
		textmeasure.MarkdownColorNeutralMuted:     .fillPaint(color.N6),
	}
	.WriteString(.SVG(textmeasure.MarkdownSVGOptions{
		Class:        "md md-native",
		RolePaint:    ,
		DisableLinks: ,
		Underline:    ,
	}))
	.WriteString(`</svg>`)
	return .String()
}

func ( *markdownRenderer) ( string) textmeasure.MarkdownSVGPaint {
	return .paint(, "fill")
}

func ( *markdownRenderer) ( string) textmeasure.MarkdownSVGPaint {
	return .paint(, "stroke")
}

func ( *markdownRenderer) (,  string) textmeasure.MarkdownSVGPaint {
	if  == "" {
		 = color.N1
	}
	if color.IsThemeColor() {
		 := textmeasure.MarkdownSVGPaint{Class:  + "-" + }
		if .inlineTheme != nil {
			.Color = d2themes.ResolveThemeColor(*.inlineTheme, )
		}
		return 
	}
	if color.IsGradient() {
		 = fmt.Sprintf("url('#%s')", color.UniqueGradientID())
	}
	return textmeasure.MarkdownSVGPaint{Color: }
}

func ( *markdownRenderer) () string {
	return .corpus.String()
}