Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions MiniPdf.Web/MiniPdf.Web.Client/I18n.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ public string T(string key)
["LoadingFont"] = "Downloading CJK font...",
["FontDownloadProgress"] = "Downloading font... {0}% ({1} / {2})",
["FontLoaded"] = "Font loaded successfully",
["CheckingLocalFont"] = "Checking local fonts...",
["LocalFontUsed"] = "Using local font: {0}",
["FontLoadFailed"] = "Font download failed, using default font",
["UploadCustomFont"] = "Custom Font",
["CustomFontHint"] = "Upload your own .ttf / .otf font for better rendering results.",
Expand Down Expand Up @@ -96,8 +94,6 @@ public string T(string key)
["LoadingFont"] = "正在下载 CJK 字体...",
["FontDownloadProgress"] = "正在下载字体... {0}% ({1} / {2})",
["FontLoaded"] = "字体加载成功",
["CheckingLocalFont"] = "正在检测本地字体...",
["LocalFontUsed"] = "使用本地字体:{0}",
["FontLoadFailed"] = "字体下载失败,将使用默认字体",
["UploadCustomFont"] = "自定义字体",
["CustomFontHint"] = "上传您自己的 .ttf / .otf 字体以获得更好的渲染效果。",
Expand Down Expand Up @@ -128,8 +124,6 @@ public string T(string key)
["LoadingFont"] = "正在下載 CJK 字型...",
["FontDownloadProgress"] = "正在下載字型... {0}% ({1} / {2})",
["FontLoaded"] = "字型載入成功",
["CheckingLocalFont"] = "正在偵測本地字型...",
["LocalFontUsed"] = "使用本地字型:{0}",
["FontLoadFailed"] = "字型下載失敗,將使用預設字型",
["UploadCustomFont"] = "自訂字型",
["CustomFontHint"] = "上傳您自己的 .ttf / .otf 字型以獲得更好的渲染效果。",
Expand Down Expand Up @@ -160,8 +154,6 @@ public string T(string key)
["LoadingFont"] = "CJK フォントをダウンロード中...",
["FontDownloadProgress"] = "フォントをダウンロード中... {0}% ({1} / {2})",
["FontLoaded"] = "フォントの読み込みが完了しました",
["CheckingLocalFont"] = "ローカルフォントを確認中...",
["LocalFontUsed"] = "ローカルフォントを使用: {0}",
["FontLoadFailed"] = "フォントのダウンロードに失敗しました。デフォルトフォントを使用します",
["UploadCustomFont"] = "カスタムフォント",
["CustomFontHint"] = ".ttf / .otf フォントをアップロードして、より良いレンダリング結果を得ることができます。",
Expand Down Expand Up @@ -192,8 +184,6 @@ public string T(string key)
["LoadingFont"] = "CJK 글꼴 다운로드 중...",
["FontDownloadProgress"] = "글꼴 다운로드 중... {0}% ({1} / {2})",
["FontLoaded"] = "글꼴 로드 완료",
["CheckingLocalFont"] = "로컬 글꼴 확인 중...",
["LocalFontUsed"] = "로컬 글꼴 사용: {0}",
["FontLoadFailed"] = "글꼴 다운로드 실패, 기본 글꼴을 사용합니다",
["UploadCustomFont"] = "사용자 정의 글꼴",
["CustomFontHint"] = ".ttf / .otf 글꼴을 업로드하여 더 나은 렌더링 결과를 얻을 수 있습니다.",
Expand Down Expand Up @@ -224,8 +214,6 @@ public string T(string key)
["LoadingFont"] = "Téléchargement de la police CJK...",
["FontDownloadProgress"] = "Téléchargement de la police... {0}% ({1} / {2})",
["FontLoaded"] = "Police chargée avec succès",
["CheckingLocalFont"] = "Vérification des polices locales...",
["LocalFontUsed"] = "Police locale utilisée : {0}",
["FontLoadFailed"] = "Échec du téléchargement de la police, utilisation de la police par défaut",
["UploadCustomFont"] = "Police personnalisée",
["CustomFontHint"] = "Téléchargez votre propre police .ttf / .otf pour de meilleurs résultats de rendu.",
Expand Down Expand Up @@ -256,8 +244,6 @@ public string T(string key)
["LoadingFont"] = "Download del font CJK in corso...",
["FontDownloadProgress"] = "Download del font in corso... {0}% ({1} / {2})",
["FontLoaded"] = "Font caricato con successo",
["CheckingLocalFont"] = "Verifica dei font locali in corso...",
["LocalFontUsed"] = "Font locale in uso: {0}",
["FontLoadFailed"] = "Download del font non riuscito, verrà usato il font predefinito",
["UploadCustomFont"] = "Font personalizzato",
["CustomFontHint"] = "Carica il tuo font .ttf / .otf per risultati di rendering migliori.",
Expand Down
77 changes: 24 additions & 53 deletions MiniPdf.Web/MiniPdf.Web.Client/Pages/Converter.razor
Original file line number Diff line number Diff line change
Expand Up @@ -233,72 +233,43 @@
if (!_fontLoaded)
{
isFontLoading = true;
fontStatus = L.T("CheckingLocalFont");
fontStatus = L.T("LoadingFont");
StateHasChanged();
await Task.Yield();

try
{
// Try Local Font Access API first (Chrome 103+, requires user permission)
string? localFontFamily = null;
try { localFontFamily = await JS.InvokeAsync<string?>("tryLoadLocalFontMeta"); } catch { }

if (localFontFamily is not null)
var request = new HttpRequestMessage(HttpMethod.Get, "fonts/NotoSansSC-Regular.ttf");
request.SetBrowserResponseStreamingEnabled(true);
using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();

var totalBytes = response.Content.Headers.ContentLength ?? -1;
using var contentStream = await response.Content.ReadAsStreamAsync();
using var fontMs = new MemoryStream();
var buffer = new byte[81920];
long totalRead = 0;
int read;

while ((read = await contentStream.ReadAsync(buffer)) > 0)
{
var jsStreamRef = await JS.InvokeAsync<IJSStreamReference?>("getLocalFontStream");
if (jsStreamRef is not null)
fontMs.Write(buffer, 0, read);
totalRead += read;
if (totalBytes > 0)
{
await using var fontStream = await jsStreamRef.OpenReadStreamAsync(maxAllowedSize: 50 * 1024 * 1024);
using var fontMs = new MemoryStream();
await fontStream.CopyToAsync(fontMs);
MiniSoftware.MiniPdf.RegisterFont(localFontFamily, fontMs.ToArray());
fontLoadSuccess = true;
fontStatus = "✓ " + string.Format(L.T("LocalFontUsed"), localFontFamily);
fontProgress = (int)(totalRead * 100 / totalBytes);
fontStatus = string.Format(L.T("FontDownloadProgress"), fontProgress, FormatSize(totalRead), FormatSize(totalBytes));
}
else
{
localFontFamily = null; // stream unexpectedly null, fall through to download
fontStatus = $"{L.T("LoadingFont")} ({FormatSize(totalRead)})";
}
}

if (localFontFamily is null)
{
// Fall back to downloading NotoSansSC
fontStatus = L.T("LoadingFont");
StateHasChanged();

var request = new HttpRequestMessage(HttpMethod.Get, "fonts/NotoSansSC-Regular.ttf");
request.SetBrowserResponseStreamingEnabled(true);
using var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();

var totalBytes = response.Content.Headers.ContentLength ?? -1;
using var contentStream = await response.Content.ReadAsStreamAsync();
using var fontMs = new MemoryStream();
var buffer = new byte[81920];
long totalRead = 0;
int read;

while ((read = await contentStream.ReadAsync(buffer)) > 0)
{
fontMs.Write(buffer, 0, read);
totalRead += read;
if (totalBytes > 0)
{
fontProgress = (int)(totalRead * 100 / totalBytes);
fontStatus = string.Format(L.T("FontDownloadProgress"), fontProgress, FormatSize(totalRead), FormatSize(totalBytes));
}
else
{
fontStatus = $"{L.T("LoadingFont")} ({FormatSize(totalRead)})";
}
StateHasChanged();
}

MiniSoftware.MiniPdf.RegisterFont("NotoSansSC", fontMs.ToArray());
fontLoadSuccess = true;
fontStatus = "✓ " + L.T("FontLoaded");
}

MiniSoftware.MiniPdf.RegisterFont("NotoSansSC", fontMs.ToArray());
fontLoadSuccess = true;
fontStatus = "✓ " + L.T("FontLoaded");
}
catch
{
Expand Down
43 changes: 0 additions & 43 deletions MiniPdf.Web/MiniPdf.Web.Client/wwwroot/js/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,3 @@ window.downloadFile = function (fileName, contentType, byteArray) {
document.body.removeChild(a);
URL.revokeObjectURL(url);
};

// Local Font Access API support (Chrome 103+)
// Returns the font-family name of the first matching CJK font, or null.
// The font blob is cached so getLocalFontStream() can return it immediately after.
let _localFontBlob = null;

window.tryLoadLocalFontMeta = async function () {
if (!('queryLocalFonts' in window)) return null;
try {
const fonts = await window.queryLocalFonts();
const preferred = [
// Windows
'Microsoft YaHei', 'Microsoft YaHei UI',
'SimSun', 'SimHei', 'FangSong', 'KaiTi',
// macOS / iOS
'PingFang SC', 'Heiti SC', 'STHeiti', 'STSong',
// Japanese (Windows / macOS)
'Meiryo', 'Yu Gothic', 'MS Gothic', 'Hiragino Sans',
// Korean (Windows / macOS)
'Malgun Gothic', 'Apple SD Gothic Neo', 'Gulim', 'Dotum',
// Google Noto / open-source
'Noto Sans CJK SC', 'Noto Sans SC', 'Source Han Sans SC',
];
let found = null;
for (const family of preferred) {
found = fonts.find(f => f.family === family && (f.style === 'Regular' || f.style === 'Normal'));
if (!found) found = fonts.find(f => f.family === family);
if (found) break;
}
if (!found) return null;
_localFontBlob = await found.blob();
return found.family;
} catch {
return null;
}
};

// Returns a ReadableStream for the cached font blob (call after tryLoadLocalFontMeta succeeds).
window.getLocalFontStream = function () {
const blob = _localFontBlob;
_localFontBlob = null; // release reference
return blob ? blob.stream() : null;
};
Loading