blob: ce161636b8ce02d100d553cb891a5520b5fe429e [file] [log] [blame]
package scrap
import (
"fmt"
"strings"
"text/template"
"go.skia.org/infra/go/skerr"
)
type templateMap map[Lang]map[Type]*template.Template
func templateName(t Type, lang Lang) string {
return fmt.Sprintf("%s-%s", t, lang)
}
// bodyAsStringSlice is a template helper function that breaks up a ScrapBody
// into a form suitable as a multi-line C++ const char * string.
//
// That is, it takes "<svg> \n</svg>"
//
// And turns it into:
//
// []string{
// `"<svg> \n"`,
// `"</svg>";`,
// }
func bodyAsStringSlice(body string) []string {
// Escape all the double quotes.
body = strings.ReplaceAll(body, `"`, `\"`)
// Break into individual lines.
lines := strings.Split(body, "\n")
numLines := len(lines)
ret := make([]string, 0, numLines)
for i, line := range lines {
// Quote each line.
quotedLine := `"` + line
if i == numLines-1 {
// Since this is the very last line, add end quote and terminating semicolon.
quotedLine += `";`
} else {
// Add newline and end quote.
quotedLine += `\n"`
}
ret = append(ret, quotedLine)
}
return ret
}
// funcMap are the template helper functions available in each template.
var funcMap = template.FuncMap{
"bodyAsStringSlice": bodyAsStringSlice,
}
func loadTemplates() (templateMap, error) {
ret := templateMap{}
for _, lang := range AllLangs {
ret[lang] = map[Type]*template.Template{}
for _, t := range AllTypes {
tmpl, err := template.New("").Funcs(funcMap).Parse(templates[templateName(t, lang)])
if err != nil {
return nil, skerr.Wrapf(err, "Failed to parse template %v %v", lang, t)
}
ret[lang][t] = tmpl
}
}
return ret, nil
}
// TODO(jcgregorio) Fill in the rest of the templates.
var templates = map[string]string{
"svg-cpp": svgCpp,
"svg-js": "",
"sksl-cpp": "",
"sksl-js": "",
"particles-cpp": "",
"particles-js": "",
}
const svgCpp = `void draw(SkCanvas* canvas) {
const char * svg ={{ range bodyAsStringSlice .Body }}
{{.}}{{end}}
sk_sp<SkData> data(SkData::MakeWithoutCopy(svg, strlen(svg)));
if (!data) {
SkDebugf("Failed to load SVG.");
return;
}
SkMemoryStream stream(std::move(data));
sk_sp<SkSVGDOM> svgDom = SkSVGDOM::MakeFromStream(stream);
if (!svgDom) {
SkDebugf("Failed to parse SVG.");
return;
}
// Use the intrinsic SVG size if available, otherwise fall back to a default value.
static const SkSize kDefaultContainerSize = SkSize::Make(128, 128);
if (svgDom->containerSize().isEmpty()) {
svgDom->setContainerSize(kDefaultContainerSize);
}
svgDom->render(canvas);
}`