package d2isometricimg

import (
	
	
	
	
	
	
	

	
	
	
	
	
)

func nativeEmbeddedAssetsOnly( *d2target.Diagram) error {
	 := func( *url.URL) error {
		if  != nil && !strings.EqualFold(.Scheme, "data") {
			return fmt.Errorf("native surface external icon requires an explicit asset resolver")
		}
		return nil
	}
	if  := (.Root.Icon);  != nil {
		return 
	}
	for ,  := range .Shapes {
		if  := (.Icon);  != nil {
			return 
		}
	}
	for ,  := range .Connections {
		if  := (.Icon);  != nil {
			return 
		}
	}
	if .Legend != nil {
		for ,  := range .Legend.Shapes {
			if  := (.Icon);  != nil {
				return 
			}
		}
		for ,  := range .Legend.Connections {
			if  := (.Icon);  != nil {
				return 
			}
		}
	}
	return nil
}

func nativeSurfaceFonts( *d2scenebuild.FontFallbackOptions) (*d2scenebuild.FontFallbackOptions, error) {
	 := d2scenebuild.FontFallbackOptions{MaxAssets: 96, MaxBytes: 64 << 20, MaxRunesPerText: maxLabelRunes, MaxTotalRunes: maxTextSourceBytes, MaxCoverageChecks: 8000000, MaxShapedGlyphs: 1000000, MaxShapingRuns: 200000, MaxFontFacesPerText: 8}
	if  != nil {
		.Resolver = .Resolver
		.MaxAssets = iconLimit(.MaxAssets, .MaxAssets)
		if .MaxBytes > 0 {
			.MaxBytes = min(.MaxBytes, .MaxBytes)
		}
		.MaxRunesPerText = iconLimit(.MaxRunesPerText, .MaxRunesPerText)
		.MaxTotalRunes = iconLimit(.MaxTotalRunes, .MaxTotalRunes)
		if .MaxCoverageChecks > 0 {
			.MaxCoverageChecks = min(.MaxCoverageChecks, .MaxCoverageChecks)
		}
		.MaxShapedGlyphs = iconLimit(.MaxShapedGlyphs, .MaxShapedGlyphs)
		.MaxShapingRuns = iconLimit(.MaxShapingRuns, .MaxShapingRuns)
		.MaxFontFacesPerText = iconLimit(.MaxFontFacesPerText, .MaxFontFacesPerText)
	}
	if .Resolver == nil {
		,  := d2fonts.NewBundledFallbackResolver(nil, d2fonts.BundledFallbackLimits{MaxRequestedRunes: .MaxTotalRunes, MaxResolvedBytes: .MaxBytes})
		if  != nil {
			return nil, 
		}
		.Resolver = 
	}
	return &, nil
}

// Reject a missing source glyph explicitly. The normal 2D renderer may draw
// a placeholder; a static 3D export must not silently present that as fidelity.
func nativeDocumentGlyphCoverage( context.Context,  *d2scene.Document) error {
	 := map[d2scene.AssetID]*fontface.ParsedFace{}
	type  struct {
		    d2scene.AssetID
		 rune
	}
	 := map[]bool{}
	 := 0
	 := func( d2scene.AssetID,  rune) (bool, error) {
		 := {, }
		if ,  := [];  {
			return , nil
		}
		++
		if  > 8000000 {
			return false, fmt.Errorf("native surface glyph coverage exceeds budget")
		}
		 := []
		if  == nil {
			,  := .Assets[].(d2scene.FontAsset)
			if ! {
				return false, fmt.Errorf("native surface font asset %q is unavailable", )
			}
			, ,  := fontface.RegisteredBundledFace(.Data, .FaceIndex)
			if  != nil {
				return false, 
			}
			if ! {
				, ,  = fontface.RegisteredBundledNotoColorEmoji(.Data, .FaceIndex)
				if  != nil {
					return false, 
				}
			}
			if  {
				,  = .CloneReadOnly()
			} else {
				,  = fontface.ParseFace(.Data, .FaceIndex)
			}
			if  != nil {
				return false, 
			}
			[] = 
		}
		,  := .SupportsRenderableRune()
		[] = 
		return , 
	}
	var  func(*d2scene.Node) error
	 = func( *d2scene.Node) error {
		if  == nil {
			return nil
		}
		if  := .Err();  != nil {
			return 
		}
		if ,  := .Primitive.(d2scene.TextRun);  {
			 := append([]d2scene.AssetID{.Font.Asset}, .Fallbacks...)
			for ,  := range .Text {
				if  == '\n' ||  == '\r' ||  == '\t' || fontface.IsDefaultIgnorableRune() {
					continue
				}
				 := false
				for ,  := range  {
					,  := (, )
					if  != nil {
						return 
					}
					if  {
						 = true
						break
					}
				}
				if ! {
					return fmt.Errorf("native surface label %q has no available font for U+%04X; configure a font or fallback resolver covering this character", .ID, )
				}
			}
		}
		for ,  := range .Children {
			if  := ();  != nil {
				return 
			}
		}
		return nil
	}
	if  := (.Root);  != nil {
		return 
	}
	for ,  := range .Assets {
		if ,  := .(d2scene.VectorAsset);  {
			if  := (.Root);  != nil {
				return 
			}
		}
	}
	return nil
}

func nativeTextNeedsFallback( context.Context,  string,  *fontface.ParsedFace) (bool, error) {
	 := map[rune]bool{}
	for ,  := range  {
		if  := .Err();  != nil {
			return false, 
		}
		if  == '\n' ||  == '\r' ||  == '\t' || fontface.IsDefaultIgnorableRune() || [] {
			continue
		}
		[] = true
		// The complete native text pipeline also handles color fonts, marks,
		// complex scripts and grapheme-cluster fallback selection.
		if  > 255 || .IsBundledNotoColorEmoji() {
			return true, nil
		}
		,  := .SupportsRenderableRune()
		if  != nil {
			return false, 
		}
		if ! {
			return true, nil
		}
	}
	return false, nil
}

func nativeFallbackTextTexture( context.Context,  string,  labelTextStyle, ,  int, ,  d2fonts.FontFamily,  *d2scenebuild.FontFallbackOptions) (*image.RGBA, textLayout, error) {
	,  = nativeFontFamilies(&, &)
	 := strings.Split(normalizeLabel(), "\n")
	 := .FontSize
	if  <= 0 {
		 = 23.5
	}
	if  > 100000 {
		return nil, textLayout{}, fmt.Errorf("native fallback text font size exceeds limit")
	}
	 := max(1, int(math.Min(100000, math.Ceil(.Width/.PixelScale))))
	 := max(1, int(math.Min(100000, math.Ceil(float64(len())**1.2))))
	 := d2target.Shape{ID: "surface-text", Type: d2target.ShapeText, Width: , Height: , Fill: "transparent", Stroke: "none", Opacity: 1, LabelPosition: "INSIDE_MIDDLE_CENTER", Text: d2target.Text{Label: normalizeLabel(), FontSize: max(1, int(math.Round())), LabelWidth: , LabelHeight: , FontFamily: "default", Color: richColor(.Color), Bold: .Bold, Italic: .Italic, Underline: .Underline}}
	if .ForegroundPaint != nil {
		.Color = .Foreground
	}
	 := d2target.NewDiagram()
	.Root.Fill, .Root.Stroke = "transparent", "none"
	.FontFamily, .MonoFontFamily = &, &
	.Shapes = []d2target.Shape{}
	,  := nativeSurfaceDocument(, , nil, )
	if  != nil {
		return nil, textLayout{}, 
	}
	, ,  := 0., math.Inf(1), math.Inf(-1)
	var  func(*d2scene.Node)
	 = func( *d2scene.Node) {
		if  == nil {
			return
		}
		if ,  := .Primitive.(d2scene.TextRun);  {
			,  := 0., 0.
			if .Ink.Valid {
				,  = .Ink.Min.X, .Ink.Max.X
				 = min(, .Origin.Y+.Ink.Min.Y)
				 = max(, .Origin.Y+.Ink.Max.Y)
			}
			for ,  := range .Glyphs {
				 = max(, .Position.X+.Advance)
			}
			if .Bold && .Italic {
				.Transform = .Transform.Mul(d2scene.Matrix{A: 1, C: -.20, D: 1, E: .20 * .Origin.Y})
				 -=  * .20
				 +=  * .20
			}
			 = max(, -)
			.Origin.X = -( + ) / 2
			.Anchor = d2scene.AnchorStart
			if .Align == "left" {
				.Origin.X = 1 - 
			}
			.Primitive = 
		}
		for ,  := range .Children {
			()
		}
	}
	(.Root)
	if !captionFinite(, ) {
		,  = 0, float64()
	}
	 := d2scene.Box{X: -( + 2) / 2, Y: min(0, -1), Width: max(1, +2), Height: max(float64(), +1) - min(0, -1)}
	if .Align == "left" {
		.X = 0
	}
	.ViewBox = 
	 := min(1, min(.Width/.PixelScale/.Width, .Depth/.PixelScale/.Height))
	if  := fitRichViewport(, );  != nil {
		return nil, textLayout{}, 
	}
	,  := rasterNativeSurfaceDocument(, , , )
	if  != nil {
		return nil, textLayout{}, 
	}
	 := image.NewRGBA(.Bounds())
	,  := nativeLabelBackground(, , , )
	if  != nil {
		return nil, textLayout{}, 
	}
	if  != nil {
		draw.Draw(, .Bounds(), , image.Point{}, draw.Src)
	}
	draw.Draw(, .Bounds(), , image.Point{}, draw.Over)
	for  := 0;  < ; ++ {
		if  := .Err();  != nil {
			return nil, textLayout{}, 
		}
		for  := 0;  < *4; ++ {
			 := *.Stride + 
			.Pix[] = uint8(math.Round(float64(.Pix[]) * .Opacity))
		}
	}
	 := *
	.LogicalWidth, .LogicalHeight = float64(), float64()
	.ViewportFit, .ViewportAlign = d2scene.ViewportMeet, d2scene.ViewportAlignXMidYMid
	if  := retainStyledNativeVectorSurface(, , &, nativeLabelBackgroundPaint(), .Opacity);  != nil {
		return nil, textLayout{}, 
	}
	return , textLayout{Lines: , FontSize:  * .PixelScale * , LineHeight:  * .PixelScale *  * 1.2}, nil
}