Merge 30ade60ee7
into bd4e943597
This commit is contained in:
commit
e087894c74
4 changed files with 33 additions and 93 deletions
|
@ -15,11 +15,6 @@ use std::{
|
|||
rc::{Rc, Weak},
|
||||
sync::Arc,
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
use windows::Win32::{
|
||||
Graphics::Imaging::{CLSID_WICImagingFactory, IWICImagingFactory},
|
||||
System::Com::{CLSCTX_INPROC_SERVER, CoCreateInstance},
|
||||
};
|
||||
|
||||
/// TestPlatform implements the Platform trait for use in tests.
|
||||
pub(crate) struct TestPlatform {
|
||||
|
@ -36,8 +31,6 @@ pub(crate) struct TestPlatform {
|
|||
screen_capture_sources: RefCell<Vec<TestScreenCaptureSource>>,
|
||||
pub opened_url: RefCell<Option<String>>,
|
||||
pub text_system: Arc<dyn PlatformTextSystem>,
|
||||
#[cfg(target_os = "windows")]
|
||||
bitmap_factory: std::mem::ManuallyDrop<IWICImagingFactory>,
|
||||
weak: Weak<Self>,
|
||||
}
|
||||
|
||||
|
@ -92,16 +85,6 @@ pub(crate) struct TestPrompts {
|
|||
|
||||
impl TestPlatform {
|
||||
pub fn new(executor: BackgroundExecutor, foreground_executor: ForegroundExecutor) -> Rc<Self> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let bitmap_factory = unsafe {
|
||||
windows::Win32::System::Ole::OleInitialize(None)
|
||||
.expect("unable to initialize Windows OLE");
|
||||
std::mem::ManuallyDrop::new(
|
||||
CoCreateInstance(&CLSID_WICImagingFactory, None, CLSCTX_INPROC_SERVER)
|
||||
.expect("Error creating bitmap factory."),
|
||||
)
|
||||
};
|
||||
|
||||
let text_system = Arc::new(NoopTextSystem);
|
||||
|
||||
Rc::new_cyclic(|weak| TestPlatform {
|
||||
|
@ -117,8 +100,6 @@ impl TestPlatform {
|
|||
current_primary_item: Mutex::new(None),
|
||||
weak: weak.clone(),
|
||||
opened_url: Default::default(),
|
||||
#[cfg(target_os = "windows")]
|
||||
bitmap_factory,
|
||||
text_system,
|
||||
})
|
||||
}
|
||||
|
@ -440,16 +421,6 @@ impl TestScreenCaptureSource {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
impl Drop for TestPlatform {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
std::mem::ManuallyDrop::drop(&mut self.bitmap_factory);
|
||||
windows::Win32::System::Ole::OleUninitialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TestKeyboardLayout;
|
||||
|
||||
impl PlatformKeyboardLayout for TestKeyboardLayout {
|
||||
|
|
|
@ -15,7 +15,6 @@ use windows::{
|
|||
DirectWrite::*,
|
||||
Dxgi::Common::*,
|
||||
Gdi::{IsRectEmpty, LOGFONTW},
|
||||
Imaging::*,
|
||||
},
|
||||
System::SystemServices::LOCALE_NAME_MAX_LENGTH,
|
||||
UI::WindowsAndMessaging::*,
|
||||
|
@ -40,7 +39,6 @@ pub(crate) struct DirectWriteTextSystem(RwLock<DirectWriteState>);
|
|||
struct DirectWriteComponent {
|
||||
locale: String,
|
||||
factory: IDWriteFactory5,
|
||||
bitmap_factory: AgileReference<IWICImagingFactory>,
|
||||
in_memory_loader: IDWriteInMemoryFontFileLoader,
|
||||
builder: IDWriteFontSetBuilder1,
|
||||
text_renderer: Arc<TextRendererWrapper>,
|
||||
|
@ -76,11 +74,10 @@ struct FontIdentifier {
|
|||
}
|
||||
|
||||
impl DirectWriteComponent {
|
||||
pub fn new(bitmap_factory: &IWICImagingFactory, gpu_context: &DirectXDevices) -> Result<Self> {
|
||||
pub fn new(gpu_context: &DirectXDevices) -> Result<Self> {
|
||||
// todo: ideally this would not be a large unsafe block but smaller isolated ones for easier auditing
|
||||
unsafe {
|
||||
let factory: IDWriteFactory5 = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED)?;
|
||||
let bitmap_factory = AgileReference::new(bitmap_factory)?;
|
||||
// The `IDWriteInMemoryFontFileLoader` here is supported starting from
|
||||
// Windows 10 Creators Update, which consequently requires the entire
|
||||
// `DirectWriteTextSystem` to run on `win10 1703`+.
|
||||
|
@ -117,7 +114,6 @@ impl DirectWriteComponent {
|
|||
Ok(DirectWriteComponent {
|
||||
locale,
|
||||
factory,
|
||||
bitmap_factory,
|
||||
in_memory_loader,
|
||||
builder,
|
||||
text_renderer,
|
||||
|
@ -212,11 +208,8 @@ impl GPUState {
|
|||
}
|
||||
|
||||
impl DirectWriteTextSystem {
|
||||
pub(crate) fn new(
|
||||
gpu_context: &DirectXDevices,
|
||||
bitmap_factory: &IWICImagingFactory,
|
||||
) -> Result<Self> {
|
||||
let components = DirectWriteComponent::new(bitmap_factory, gpu_context)?;
|
||||
pub(crate) fn new(gpu_context: &DirectXDevices) -> Result<Self> {
|
||||
let components = DirectWriteComponent::new(gpu_context)?;
|
||||
let system_font_collection = unsafe {
|
||||
let mut result = std::mem::zeroed();
|
||||
components
|
||||
|
@ -782,8 +775,8 @@ impl DirectWriteState {
|
|||
rendering_mode,
|
||||
DWRITE_MEASURING_MODE_NATURAL,
|
||||
grid_fit_mode,
|
||||
// We're using cleartype not grayscale for monochrome is because it provides better quality
|
||||
DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
|
||||
// Use grayscale antialiasing for consistent quality across all color combinations
|
||||
DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
|
||||
baseline_origin_x,
|
||||
baseline_origin_y,
|
||||
)
|
||||
|
@ -794,8 +787,8 @@ impl DirectWriteState {
|
|||
fn raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>> {
|
||||
let glyph_analysis = self.create_glyph_run_analysis(params)?;
|
||||
|
||||
let bounds = unsafe { glyph_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1)? };
|
||||
// Some glyphs cannot be drawn with ClearType, such as bitmap fonts. In that case
|
||||
let bounds = unsafe { glyph_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_ALIASED_1x1)? };
|
||||
// Some glyphs cannot be drawn with antialiasing, such as bitmap fonts. In that case
|
||||
// GetAlphaTextureBounds() supposedly returns an empty RECT, but I haven't tested that yet.
|
||||
if !unsafe { IsRectEmpty(&bounds) }.as_bool() {
|
||||
Ok(Bounds {
|
||||
|
@ -871,49 +864,25 @@ impl DirectWriteState {
|
|||
params: &RenderGlyphParams,
|
||||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<Vec<u8>> {
|
||||
let mut bitmap_data =
|
||||
vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize * 3];
|
||||
// Use single-channel grayscale data directly from DirectWrite
|
||||
let mut grayscale_data =
|
||||
vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize];
|
||||
|
||||
let glyph_analysis = self.create_glyph_run_analysis(params)?;
|
||||
unsafe {
|
||||
glyph_analysis.CreateAlphaTexture(
|
||||
// We're using cleartype not grayscale for monochrome is because it provides better quality
|
||||
DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
DWRITE_TEXTURE_ALIASED_1x1,
|
||||
&RECT {
|
||||
left: glyph_bounds.origin.x.0,
|
||||
top: glyph_bounds.origin.y.0,
|
||||
right: glyph_bounds.size.width.0 + glyph_bounds.origin.x.0,
|
||||
bottom: glyph_bounds.size.height.0 + glyph_bounds.origin.y.0,
|
||||
},
|
||||
&mut bitmap_data,
|
||||
&mut grayscale_data,
|
||||
)?;
|
||||
}
|
||||
|
||||
let bitmap_factory = self.components.bitmap_factory.resolve()?;
|
||||
let bitmap = unsafe {
|
||||
bitmap_factory.CreateBitmapFromMemory(
|
||||
glyph_bounds.size.width.0 as u32,
|
||||
glyph_bounds.size.height.0 as u32,
|
||||
&GUID_WICPixelFormat24bppRGB,
|
||||
glyph_bounds.size.width.0 as u32 * 3,
|
||||
&bitmap_data,
|
||||
)
|
||||
}?;
|
||||
|
||||
let grayscale_bitmap =
|
||||
unsafe { WICConvertBitmapSource(&GUID_WICPixelFormat8bppGray, &bitmap) }?;
|
||||
|
||||
let mut bitmap_data =
|
||||
vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize];
|
||||
unsafe {
|
||||
grayscale_bitmap.CopyPixels(
|
||||
std::ptr::null() as _,
|
||||
glyph_bounds.size.width.0 as u32,
|
||||
&mut bitmap_data,
|
||||
)
|
||||
}?;
|
||||
|
||||
Ok(bitmap_data)
|
||||
Ok(grayscale_data)
|
||||
}
|
||||
|
||||
fn rasterize_color(
|
||||
|
@ -981,25 +950,24 @@ impl DirectWriteState {
|
|||
DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC,
|
||||
DWRITE_MEASURING_MODE_NATURAL,
|
||||
DWRITE_GRID_FIT_MODE_DEFAULT,
|
||||
DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
|
||||
DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
|
||||
baseline_origin_x,
|
||||
baseline_origin_y,
|
||||
)
|
||||
}?;
|
||||
|
||||
let color_bounds =
|
||||
unsafe { color_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1) }?;
|
||||
unsafe { color_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_ALIASED_1x1) }?;
|
||||
|
||||
let color_size = size(
|
||||
color_bounds.right - color_bounds.left,
|
||||
color_bounds.bottom - color_bounds.top,
|
||||
);
|
||||
if color_size.width > 0 && color_size.height > 0 {
|
||||
let mut alpha_data =
|
||||
vec![0u8; (color_size.width * color_size.height * 3) as usize];
|
||||
let mut alpha_data = vec![0u8; (color_size.width * color_size.height) as usize];
|
||||
unsafe {
|
||||
color_analysis.CreateAlphaTexture(
|
||||
DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
DWRITE_TEXTURE_ALIASED_1x1,
|
||||
&color_bounds,
|
||||
&mut alpha_data,
|
||||
)
|
||||
|
@ -1016,8 +984,8 @@ impl DirectWriteState {
|
|||
};
|
||||
let bounds = bounds(point(color_bounds.left, color_bounds.top), color_size);
|
||||
let alpha_data = alpha_data
|
||||
.chunks_exact(3)
|
||||
.flat_map(|chunk| [chunk[0], chunk[1], chunk[2], 255])
|
||||
.iter()
|
||||
.flat_map(|&alpha| [255, 255, 255, alpha])
|
||||
.collect::<Vec<_>>();
|
||||
glyph_layers.push(GlyphLayerTexture::new(
|
||||
&self.components.gpu_state,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
ffi::OsStr,
|
||||
mem::ManuallyDrop,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
|
@ -18,10 +17,7 @@ use windows::{
|
|||
UI::ViewManagement::UISettings,
|
||||
Win32::{
|
||||
Foundation::*,
|
||||
Graphics::{
|
||||
Gdi::*,
|
||||
Imaging::{CLSID_WICImagingFactory, IWICImagingFactory},
|
||||
},
|
||||
Graphics::Gdi::*,
|
||||
Security::Credentials::*,
|
||||
System::{Com::*, LibraryLoader::*, Ole::*, SystemInformation::*, Threading::*},
|
||||
UI::{Input::KeyboardAndMouse::*, Shell::*, WindowsAndMessaging::*},
|
||||
|
@ -41,7 +37,6 @@ pub(crate) struct WindowsPlatform {
|
|||
foreground_executor: ForegroundExecutor,
|
||||
text_system: Arc<DirectWriteTextSystem>,
|
||||
windows_version: WindowsVersion,
|
||||
bitmap_factory: ManuallyDrop<IWICImagingFactory>,
|
||||
drop_target_helper: IDropTargetHelper,
|
||||
validation_number: usize,
|
||||
main_thread_id_win32: u32,
|
||||
|
@ -101,12 +96,8 @@ impl WindowsPlatform {
|
|||
let foreground_executor = ForegroundExecutor::new(dispatcher);
|
||||
let directx_devices = DirectXDevices::new(disable_direct_composition)
|
||||
.context("Unable to init directx devices.")?;
|
||||
let bitmap_factory = ManuallyDrop::new(unsafe {
|
||||
CoCreateInstance(&CLSID_WICImagingFactory, None, CLSCTX_INPROC_SERVER)
|
||||
.context("Error creating bitmap factory.")?
|
||||
});
|
||||
let text_system = Arc::new(
|
||||
DirectWriteTextSystem::new(&directx_devices, &bitmap_factory)
|
||||
DirectWriteTextSystem::new(&directx_devices)
|
||||
.context("Error creating DirectWriteTextSystem")?,
|
||||
);
|
||||
let drop_target_helper: IDropTargetHelper = unsafe {
|
||||
|
@ -128,7 +119,6 @@ impl WindowsPlatform {
|
|||
text_system,
|
||||
disable_direct_composition,
|
||||
windows_version,
|
||||
bitmap_factory,
|
||||
drop_target_helper,
|
||||
validation_number,
|
||||
main_thread_id_win32,
|
||||
|
@ -716,7 +706,6 @@ impl Platform for WindowsPlatform {
|
|||
impl Drop for WindowsPlatform {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ManuallyDrop::drop(&mut self.bitmap_factory);
|
||||
OleUninitialize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1098,6 +1098,18 @@ MonochromeSpriteVertexOutput monochrome_sprite_vertex(uint vertex_id: SV_VertexI
|
|||
|
||||
float4 monochrome_sprite_fragment(MonochromeSpriteFragmentInput input): SV_Target {
|
||||
float sample = t_sprite.Sample(s_sprite, input.tile_position).r;
|
||||
|
||||
float textLuminance = dot(input.color.rgb, float3(0.2126, 0.7152, 0.0722));
|
||||
bool isLightText = textLuminance > 0.5;
|
||||
|
||||
if (isLightText) {
|
||||
// Stronger gamma correction - try values from 0.4 to 0.6
|
||||
sample = pow(sample, 0.45);
|
||||
|
||||
// More aggressive bias to strengthen thin features
|
||||
sample = saturate(sample * 1.2 - 0.1);
|
||||
}
|
||||
|
||||
return float4(input.color.rgb, input.color.a * sample);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue