upload sdk

git-svn-id: svn://kolibrios.org@4349 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge)
2013-12-15 08:09:20 +00:00
parent 6c6781f799
commit 754f9336f0
5801 changed files with 1688660 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
STACK_SIZE equ 4096
include "app.inc"
align 8
main:
cinvoke _printf, msg_hello
ret
msg_hello db 'Hello world!',0x0D,0x0A,0
align 16
__idata_start:
library libc,'libc.dll'
include 'libc.inc'
__idata_end:
__iend:
__cmdline: rb 256
__pgmname: rb 1024
rb 16
__stack:
__bssend:

View File

@@ -0,0 +1,283 @@
include 'import32.inc'
include 'proc32.inc'
use32
org 0x0
db 'MENUET02'
dd 0x01
dd __start
dd __iend
dd __bssend
dd __stack
dd __cmdline
dd __pgmname
dd 0x0
dd __idata_start
dd __idata_end
dd main
IMAGE_DOS_SIGNATURE equ 0x5A4D
IMAGE_NT_SIGNATURE equ 0x00004550
IMAGE_FILE_MACHINE_I386 equ 0x014c
IMAGE_NT_OPTIONAL_HDR32_MAGIC equ 0x10B
IMAGE_NT_HEADERS32_SIZE equ 0xF8
__start:
.e_lfanew equ 0x3C
.FileHeader.NumberOfSections equ 0x06
.OptionalHeader.ImageBase equ 0x34
.SectionAlignment equ 0x38
.FileAlignment equ 0x3C
.OptionalHeader.SizeOfImage equ 0x50
.OptionalHeader.SizeOfHeaders equ 0x54
.VirtualAddress equ 0x0C
.SizeOfRawData equ 0x10
.PointerToRawData equ 0x14
.OptionalHeader.RelocDataDirectory.VirtualAddress equ 0xA0
.OptionalHeader.RelocDataDirectory.Size equ 0xA4
.SizeOfBlock equ 0x04
mov eax, 68
mov ebx, 12
mov ecx, STACK_SIZE
add ecx, 4095
and ecx, -4096
int 0x40
test eax, eax
jz .exit
add ecx, eax
mov [fs:8], eax
mov [fs:12], ecx
mov esp, ecx
sub esp, 1024
mov eax, 9
mov ebx, esp
mov ecx, -1
int 0x40
mov eax, [ebx+30]
mov [fs:0], eax
add esp, 1024
mov eax, 68
mov ebx, 27
mov ecx, libc_path
int 0x40
test eax, eax
jz .exit
push edx
push eax
.validate_pe:
cmp edx, 0x3F
jbe .exit
cmp word [eax], IMAGE_DOS_SIGNATURE
jne .exit
mov edx, [eax+.e_lfanew]
test edx, edx
jz .exit
add edx, eax ;edx = nt header
jb .exit
cmp dword [edx], IMAGE_NT_SIGNATURE
jnz .exit
cmp word [edx+0x04], IMAGE_FILE_MACHINE_I386
jnz .exit
cmp word [edx+0x18], IMAGE_NT_OPTIONAL_HDR32_MAGIC
jnz .exit
mov ecx, [edx+.SectionAlignment]
cmp ecx, 4095
ja .l1
cmp ecx, [edx+.FileAlignment]
jne .exit
jmp @F
.l1:
cmp ecx, [edx+.FileAlignment]
jb .exit
@@:
test ecx, ecx
jz .exit
lea eax, [ecx-1]
test ecx, eax
jnz .exit
mov ecx, [edx+.FileAlignment]
test ecx, ecx
jz .exit
lea ebx, [ecx-1]
test ecx, ebx
jnz .exit
cmp word [edx+.FileHeader.NumberOfSections], 96
ja .exit
.create_image:
mov ecx, [edx+.OptionalHeader.SizeOfImage]
mov eax, 68
mov ebx, 12
int 0x40
mov ebp, eax
test eax, eax
jz .exit_2
mov ecx, [edx+.OptionalHeader.SizeOfHeaders]
mov esi, [esp]
mov edi, eax
shr ecx, 2 ;copy header
rep movsd
lea eax, [edx+IMAGE_NT_HEADERS32_SIZE] ;eax = MAGE_SECTION_HEADER
movzx ebx, word [edx+.FileHeader.NumberOfSections]
test ebx, ebx
jz @F
.copy_loop:
mov ecx, [eax+.SizeOfRawData]
test ecx, ecx
jz .next_section
mov esi, [eax+.PointerToRawData]
test esi, esi
jz .next_section
add esi, [esp]
mov edi, [eax+.VirtualAddress]
add edi, ebp
shr ecx, 2
rep movsd
;copy section
.next_section:
add eax, 0x28
dec ebx
jnz .copy_loop
@@:
push edx
mov esi, [edx+.OptionalHeader.RelocDataDirectory.Size]
test esi, esi
jz .call_libc
mov ebx, ebp
sub ebx, [edx+.OptionalHeader.ImageBase] ;delta
mov edx, [edx+.OptionalHeader.RelocDataDirectory.VirtualAddress]
lea ecx, [ebp+edx] ;IMAGE_BASE_RELOCATION
mov eax, [ecx+.SizeOfBlock]
test eax, eax
jz .unmap_relocs
mov esi, ebx
shr esi, 16
push esi
align 4
.loop_block:
sub eax, 8
lea edx, [ecx+8] ;entry
shr eax, 1
jz .next_block
lea edi, [ecx+eax*2+8] ;last entry
align 4
.loop_reloc:
mov si, [edx]
mov eax, esi
and eax, 0FFFh
add eax, [ecx] ;offset
shr si, 12 ;reloc type
dec si
jnz @F
.type_1:
mov esi, [esp]
add [eax+ebp], si
jmp .next_entry
@@:
dec si
jnz @F
.type_2:
add [eax+ebp], bx
jmp .next_entry
@@:
dec si
jnz .next_entry
.type_3:
add [eax+ebp], ebx
.next_entry:
add edx, 2
cmp edx, edi
jne .loop_reloc
.next_block:
add ecx, [ecx+.SizeOfBlock]
mov eax, [ecx+.SizeOfBlock]
test eax, eax
jnz .loop_block
add esp, 4
pop edx
mov esi, [edx+.OptionalHeader.RelocDataDirectory.Size]
mov edx, [edx+.OptionalHeader.RelocDataDirectory.VirtualAddress]
.unmap_relocs:
mov ebx, 26
mov eax, 68
mov ecx, ebp
int 0x40
.call_libc:
push ebp
mov edx, [ebp+0x3C]
add ebp, [ebp+edx+0x28]
call ebp
.exit_2:
.exit:
or eax, -1
int 0x40
libc_path db '/kolibrios/lib/libc.dll',0

View File

@@ -0,0 +1,275 @@
import avcodec-54,\
audio_resample,'audio_resample',\
audio_resample_close,'audio_resample_close',\
av_audio_convert,'av_audio_convert',\
av_audio_convert_alloc,'av_audio_convert_alloc',\
av_audio_convert_free,'av_audio_convert_free',\
av_audio_resample_init,'av_audio_resample_init',\
av_bitstream_filter_close,'av_bitstream_filter_close',\
av_bitstream_filter_filter,'av_bitstream_filter_filter',\
av_bitstream_filter_init,'av_bitstream_filter_init',\
av_bitstream_filter_next,'av_bitstream_filter_next',\
av_codec_get_codec_descriptor,'av_codec_get_codec_descriptor',\
av_codec_get_pkt_timebase,'av_codec_get_pkt_timebase',\
av_codec_is_decoder,'av_codec_is_decoder',\
av_codec_is_encoder,'av_codec_is_encoder',\
av_codec_next,'av_codec_next',\
av_codec_set_codec_descriptor,'av_codec_set_codec_descriptor',\
av_codec_set_pkt_timebase,'av_codec_set_pkt_timebase',\
av_copy_packet,'av_copy_packet',\
av_dct_calc,'av_dct_calc',\
av_dct_end,'av_dct_end',\
av_dct_init,'av_dct_init',\
av_destruct_packet,'av_destruct_packet',\
av_dup_packet,'av_dup_packet',\
av_fast_malloc,'av_fast_malloc',\
av_fast_padded_malloc,'av_fast_padded_malloc',\
av_fast_padded_mallocz,'av_fast_padded_mallocz',\
av_fast_realloc,'av_fast_realloc',\
av_fft_calc,'av_fft_calc',\
av_fft_end,'av_fft_end',\
av_fft_init,'av_fft_init',\
av_fft_permute,'av_fft_permute',\
av_frame_get_best_effort_timestamp,'av_frame_get_best_effort_timestamp',\
av_frame_get_channel_layout,'av_frame_get_channel_layout',\
av_frame_get_channels,'av_frame_get_channels',\
av_frame_get_decode_error_flags,'av_frame_get_decode_error_flags',\
av_frame_get_metadata,'av_frame_get_metadata',\
av_frame_get_pkt_duration,'av_frame_get_pkt_duration',\
av_frame_get_pkt_pos,'av_frame_get_pkt_pos',\
av_frame_get_pkt_size,'av_frame_get_pkt_size',\
av_frame_get_sample_rate,'av_frame_get_sample_rate',\
av_frame_set_best_effort_timestamp,'av_frame_set_best_effort_timestamp',\
av_frame_set_channel_layout,'av_frame_set_channel_layout',\
av_frame_set_channels,'av_frame_set_channels',\
av_frame_set_decode_error_flags,'av_frame_set_decode_error_flags',\
av_frame_set_metadata,'av_frame_set_metadata',\
av_frame_set_pkt_duration,'av_frame_set_pkt_duration',\
av_frame_set_pkt_pos,'av_frame_set_pkt_pos',\
av_frame_set_pkt_size,'av_frame_set_pkt_size',\
av_frame_set_sample_rate,'av_frame_set_sample_rate',\
av_free_packet,'av_free_packet',\
av_get_audio_frame_duration,'av_get_audio_frame_duration',\
av_get_bits_per_sample,'av_get_bits_per_sample',\
av_get_codec_tag_string,'av_get_codec_tag_string',\
av_get_exact_bits_per_sample,'av_get_exact_bits_per_sample',\
av_get_pcm_codec,'av_get_pcm_codec',\
av_get_profile_name,'av_get_profile_name',\
av_grow_packet,'av_grow_packet',\
av_hwaccel_next,'av_hwaccel_next',\
av_imdct_calc,'av_imdct_calc',\
av_imdct_half,'av_imdct_half',\
av_init_packet,'av_init_packet',\
av_lockmgr_register,'av_lockmgr_register',\
av_log_ask_for_sample,'av_log_ask_for_sample',\
av_log_missing_feature,'av_log_missing_feature',\
av_mdct_calc,'av_mdct_calc',\
av_mdct_end,'av_mdct_end',\
av_mdct_init,'av_mdct_init',\
av_new_packet,'av_new_packet',\
av_packet_get_side_data,'av_packet_get_side_data',\
av_packet_merge_side_data,'av_packet_merge_side_data',\
av_packet_new_side_data,'av_packet_new_side_data',\
av_packet_shrink_side_data,'av_packet_shrink_side_data',\
av_packet_split_side_data,'av_packet_split_side_data',\
av_parser_change,'av_parser_change',\
av_parser_close,'av_parser_close',\
av_parser_init,'av_parser_init',\
av_parser_next,'av_parser_next',\
av_parser_parse2,'av_parser_parse2',\
av_picture_copy,'av_picture_copy',\
av_picture_crop,'av_picture_crop',\
av_picture_pad,'av_picture_pad',\
av_rdft_calc,'av_rdft_calc',\
av_rdft_end,'av_rdft_end',\
av_rdft_init,'av_rdft_init',\
av_register_bitstream_filter,'av_register_bitstream_filter',\
av_register_codec_parser,'av_register_codec_parser',\
av_register_hwaccel,'av_register_hwaccel',\
av_resample,'av_resample',\
av_resample_close,'av_resample_close',\
av_resample_compensate,'av_resample_compensate',\
av_resample_init,'av_resample_init',\
av_shrink_packet,'av_shrink_packet',\
av_xiphlacing,'av_xiphlacing',\
avcodec_align_dimensions,'avcodec_align_dimensions',\
avcodec_align_dimensions2,'avcodec_align_dimensions2',\
avcodec_alloc_context,'avcodec_alloc_context',\
avcodec_alloc_context2,'avcodec_alloc_context2',\
avcodec_alloc_context3,'avcodec_alloc_context3',\
avcodec_alloc_frame,'avcodec_alloc_frame',\
avcodec_close,'avcodec_close',\
avcodec_configuration,'avcodec_configuration',\
avcodec_copy_context,'avcodec_copy_context',\
avcodec_decode_audio3,'avcodec_decode_audio3',\
avcodec_decode_audio4,'avcodec_decode_audio4',\
avcodec_decode_subtitle2,'avcodec_decode_subtitle2',\
avcodec_decode_video2,'avcodec_decode_video2',\
avcodec_default_execute,'avcodec_default_execute',\
avcodec_default_execute2,'avcodec_default_execute2',\
avcodec_default_free_buffers,'avcodec_default_free_buffers',\
avcodec_default_get_buffer,'avcodec_default_get_buffer',\
avcodec_default_get_format,'avcodec_default_get_format',\
avcodec_default_reget_buffer,'avcodec_default_reget_buffer',\
avcodec_default_release_buffer,'avcodec_default_release_buffer',\
avcodec_descriptor_get,'avcodec_descriptor_get',\
avcodec_descriptor_get_by_name,'avcodec_descriptor_get_by_name',\
avcodec_descriptor_next,'avcodec_descriptor_next',\
avcodec_encode_audio,'avcodec_encode_audio',\
avcodec_encode_audio2,'avcodec_encode_audio2',\
avcodec_encode_subtitle,'avcodec_encode_subtitle',\
avcodec_encode_video,'avcodec_encode_video',\
avcodec_encode_video2,'avcodec_encode_video2',\
avcodec_fill_audio_frame,'avcodec_fill_audio_frame',\
avcodec_find_best_pix_fmt,'avcodec_find_best_pix_fmt',\
avcodec_find_best_pix_fmt2,'avcodec_find_best_pix_fmt2',\
avcodec_find_best_pix_fmt_of_2,'avcodec_find_best_pix_fmt_of_2',\
avcodec_find_best_pix_fmt_of_list,'avcodec_find_best_pix_fmt_of_list',\
avcodec_find_decoder,'avcodec_find_decoder',\
avcodec_find_decoder_by_name,'avcodec_find_decoder_by_name',\
avcodec_find_encoder,'avcodec_find_encoder',\
avcodec_find_encoder_by_name,'avcodec_find_encoder_by_name',\
avcodec_flush_buffers,'avcodec_flush_buffers',\
avcodec_free_frame,'avcodec_free_frame',\
avcodec_get_chroma_sub_sample,'avcodec_get_chroma_sub_sample',\
avcodec_get_class,'avcodec_get_class',\
avcodec_get_context_defaults,'avcodec_get_context_defaults',\
avcodec_get_context_defaults2,'avcodec_get_context_defaults2',\
avcodec_get_context_defaults3,'avcodec_get_context_defaults3',\
avcodec_get_edge_width,'avcodec_get_edge_width',\
avcodec_get_frame_class,'avcodec_get_frame_class',\
avcodec_get_frame_defaults,'avcodec_get_frame_defaults',\
avcodec_get_name,'avcodec_get_name',\
avcodec_get_pix_fmt_loss,'avcodec_get_pix_fmt_loss',\
avcodec_get_subtitle_rect_class,'avcodec_get_subtitle_rect_class',\
avcodec_get_type,'avcodec_get_type',\
avcodec_is_open,'avcodec_is_open',\
avcodec_license,'avcodec_license',\
avcodec_open,'avcodec_open',\
avcodec_open2,'avcodec_open2',\
avcodec_pix_fmt_to_codec_tag,'avcodec_pix_fmt_to_codec_tag',\
avcodec_register,'avcodec_register',\
avcodec_register_all,'avcodec_register_all',\
avcodec_set_dimensions,'avcodec_set_dimensions',\
avcodec_string,'avcodec_string',\
avcodec_version,'avcodec_version',\
avpicture_alloc,'avpicture_alloc',\
avpicture_deinterlace,'avpicture_deinterlace',\
avpicture_fill,'avpicture_fill',\
avpicture_free,'avpicture_free',\
avpicture_get_size,'avpicture_get_size',\
avpicture_layout,'avpicture_layout',\
avpriv_aac_parse_header,'avpriv_aac_parse_header',\
avpriv_ac3_channel_layout_tab,'avpriv_ac3_channel_layout_tab',\
avpriv_ac3_parse_header,'avpriv_ac3_parse_header',\
avpriv_adx_decode_header,'avpriv_adx_decode_header',\
avpriv_align_put_bits,'avpriv_align_put_bits',\
avpriv_bprint_to_extradata,'avpriv_bprint_to_extradata',\
avpriv_check_timecode_rate,'avpriv_check_timecode_rate',\
avpriv_copy_bits,'avpriv_copy_bits',\
avpriv_copy_pce_data,'avpriv_copy_pce_data',\
avpriv_dca_sample_rates,'avpriv_dca_sample_rates',\
avpriv_dirac_parse_sequence_header,'avpriv_dirac_parse_sequence_header',\
avpriv_dnxhd_get_frame_size,'avpriv_dnxhd_get_frame_size',\
avpriv_dv_codec_profile,'avpriv_dv_codec_profile',\
avpriv_dv_frame_profile,'avpriv_dv_frame_profile',\
avpriv_dv_frame_profile2,'avpriv_dv_frame_profile2',\
avpriv_flac_is_extradata_valid,'avpriv_flac_is_extradata_valid',\
avpriv_flac_parse_block_header,'avpriv_flac_parse_block_header',\
avpriv_flac_parse_streaminfo,'avpriv_flac_parse_streaminfo',\
avpriv_framenum_to_drop_timecode,'avpriv_framenum_to_drop_timecode',\
avpriv_framenum_to_smpte_timecode,'avpriv_framenum_to_smpte_timecode',\
avpriv_h264_has_num_reorder_frames,'avpriv_h264_has_num_reorder_frames',\
avpriv_init_smpte_timecode,'avpriv_init_smpte_timecode',\
avpriv_lock_avformat,'avpriv_lock_avformat',\
avpriv_mjpeg_bits_ac_chrominance,'avpriv_mjpeg_bits_ac_chrominance',\
avpriv_mjpeg_bits_ac_luminance,'avpriv_mjpeg_bits_ac_luminance',\
avpriv_mjpeg_bits_dc_chrominance,'avpriv_mjpeg_bits_dc_chrominance',\
avpriv_mjpeg_bits_dc_luminance,'avpriv_mjpeg_bits_dc_luminance',\
avpriv_mjpeg_val_ac_chrominance,'avpriv_mjpeg_val_ac_chrominance',\
avpriv_mjpeg_val_ac_luminance,'avpriv_mjpeg_val_ac_luminance',\
avpriv_mjpeg_val_dc,'avpriv_mjpeg_val_dc',\
avpriv_mpa_bitrate_tab,'avpriv_mpa_bitrate_tab',\
avpriv_mpa_decode_header,'avpriv_mpa_decode_header',\
avpriv_mpa_freq_tab,'avpriv_mpa_freq_tab',\
avpriv_mpeg4audio_get_config,'avpriv_mpeg4audio_get_config',\
avpriv_mpeg4audio_sample_rates,'avpriv_mpeg4audio_sample_rates',\
avpriv_mpegaudio_decode_header,'avpriv_mpegaudio_decode_header',\
avpriv_mpv_find_start_code,'avpriv_mpv_find_start_code',\
avpriv_put_string,'avpriv_put_string',\
avpriv_split_xiph_headers,'avpriv_split_xiph_headers',\
avpriv_tak_parse_streaminfo,'avpriv_tak_parse_streaminfo',\
avpriv_timecode_to_string,'avpriv_timecode_to_string',\
avpriv_toupper4,'avpriv_toupper4',\
avpriv_unlock_avformat,'avpriv_unlock_avformat',\
avpriv_vorbis_parse_extradata,'avpriv_vorbis_parse_extradata',\
avpriv_vorbis_parse_frame,'avpriv_vorbis_parse_frame',\
avpriv_vorbis_parse_reset,'avpriv_vorbis_parse_reset',\
avsubtitle_free,'avsubtitle_free',\
dsputil_init,'dsputil_init',\
ff_aanscales,'ff_aanscales',\
ff_dct32_fixed,'ff_dct32_fixed',\
ff_dct32_float,'ff_dct32_float',\
ff_dct32_float_sse,'ff_dct32_float_sse',\
ff_dct32_float_sse2,'ff_dct32_float_sse2',\
ff_dct_common_init,'ff_dct_common_init',\
ff_dct_end,'ff_dct_end',\
ff_dct_init,'ff_dct_init',\
ff_dct_init_x86,'ff_dct_init_x86',\
ff_dnxhd_cid_table,'ff_dnxhd_cid_table',\
ff_dnxhd_get_cid_table,'ff_dnxhd_get_cid_table',\
ff_faanidct,'ff_faanidct',\
ff_faanidct_add,'ff_faanidct_add',\
ff_faanidct_put,'ff_faanidct_put',\
ff_fdct_mmx,'ff_fdct_mmx',\
ff_fdct_mmxext,'ff_fdct_mmxext',\
ff_fdct_sse2,'ff_fdct_sse2',\
ff_fft_calc_3dnow,'ff_fft_calc_3dnow',\
ff_fft_calc_3dnowext,'ff_fft_calc_3dnowext',\
ff_fft_calc_sse,'ff_fft_calc_sse',\
ff_fft_end,'ff_fft_end',\
ff_fft_end_fixed,'ff_fft_end_fixed',\
ff_fft_init,'ff_fft_init',\
ff_fft_init_fixed,'ff_fft_init_fixed',\
ff_fft_init_x86,'ff_fft_init_x86',\
ff_fft_permute_sse,'ff_fft_permute_sse',\
ff_find_pix_fmt,'ff_find_pix_fmt',\
ff_framenum_to_drop_timecode,'ff_framenum_to_drop_timecode',\
ff_framenum_to_smtpe_timecode,'ff_framenum_to_smtpe_timecode',\
ff_idct_xvid_mmx,'ff_idct_xvid_mmx',\
ff_idct_xvid_mmx_add,'ff_idct_xvid_mmx_add',\
ff_idct_xvid_mmx_put,'ff_idct_xvid_mmx_put',\
ff_idct_xvid_mmxext,'ff_idct_xvid_mmxext',\
ff_idct_xvid_mmxext_add,'ff_idct_xvid_mmxext_add',\
ff_idct_xvid_mmxext_put,'ff_idct_xvid_mmxext_put',\
ff_idct_xvid_sse2,'ff_idct_xvid_sse2',\
ff_idct_xvid_sse2_add,'ff_idct_xvid_sse2_add',\
ff_idct_xvid_sse2_put,'ff_idct_xvid_sse2_put',\
ff_init_smtpe_timecode,'ff_init_smtpe_timecode',\
ff_mdct_calc_c,'ff_mdct_calc_c',\
ff_mdct_calc_c_fixed,'ff_mdct_calc_c_fixed',\
ff_mdct_calcw_c,'ff_mdct_calcw_c',\
ff_mdct_end,'ff_mdct_end',\
ff_mdct_end_fixed,'ff_mdct_end_fixed',\
ff_mdct_init,'ff_mdct_init',\
ff_mdct_init_fixed,'ff_mdct_init_fixed',\
ff_mdct_win_fixed,'ff_mdct_win_fixed',\
ff_mdct_win_float,'ff_mdct_win_float',\
ff_mmx_idct,'ff_mmx_idct',\
ff_mmxext_idct,'ff_mmxext_idct',\
ff_raw_pix_fmt_tags,'ff_raw_pix_fmt_tags',\
ff_rdft_end,'ff_rdft_end',\
ff_rdft_init,'ff_rdft_init',\
ff_simple_idct248_put,'ff_simple_idct248_put',\
ff_simple_idct44_add,'ff_simple_idct44_add',\
ff_simple_idct48_add,'ff_simple_idct48_add',\
ff_simple_idct84_add,'ff_simple_idct84_add',\
ff_simple_idct_10,'ff_simple_idct_10',\
ff_simple_idct_8,'ff_simple_idct_8',\
ff_simple_idct_add_10,'ff_simple_idct_add_10',\
ff_simple_idct_add_8,'ff_simple_idct_add_8',\
ff_simple_idct_add_mmx,'ff_simple_idct_add_mmx',\
ff_simple_idct_mmx,'ff_simple_idct_mmx',\
ff_simple_idct_put_10,'ff_simple_idct_put_10',\
ff_simple_idct_put_8,'ff_simple_idct_put_8',\
ff_simple_idct_put_mmx,'ff_simple_idct_put_mmx'

View File

@@ -0,0 +1,5 @@
import avdevice-54,\
avdevice_configuration,'avdevice_configuration',\
avdevice_license,'avdevice_license',\
avdevice_register_all,'avdevice_register_all',\
avdevice_version,'avdevice_version'

View File

@@ -0,0 +1,132 @@
import avformat-54,\
av_add_index_entry,'av_add_index_entry',\
av_append_packet,'av_append_packet',\
av_close_input_file,'av_close_input_file',\
av_codec_get_id,'av_codec_get_id',\
av_codec_get_tag,'av_codec_get_tag',\
av_convert_lang_to,'av_convert_lang_to',\
av_demuxer_open,'av_demuxer_open',\
av_dump_format,'av_dump_format',\
av_filename_number_test,'av_filename_number_test',\
av_find_best_stream,'av_find_best_stream',\
av_find_default_stream_index,'av_find_default_stream_index',\
av_find_input_format,'av_find_input_format',\
av_find_program_from_stream,'av_find_program_from_stream',\
av_find_stream_info,'av_find_stream_info',\
av_fmt_ctx_get_duration_estimation_method,'av_fmt_ctx_get_duration_estimation_method',\
av_get_frame_filename,'av_get_frame_filename',\
av_get_output_timestamp,'av_get_output_timestamp',\
av_get_packet,'av_get_packet',\
av_gettime,'av_gettime',\
av_guess_codec,'av_guess_codec',\
av_guess_format,'av_guess_format',\
av_guess_sample_aspect_ratio,'av_guess_sample_aspect_ratio',\
av_hex_dump,'av_hex_dump',\
av_hex_dump_log,'av_hex_dump_log',\
av_iformat_next,'av_iformat_next',\
av_index_search_timestamp,'av_index_search_timestamp',\
av_interleave_packet_per_dts,'av_interleave_packet_per_dts',\
av_interleaved_write_frame,'av_interleaved_write_frame',\
av_match_ext,'av_match_ext',\
av_new_program,'av_new_program',\
av_new_stream,'av_new_stream',\
av_oformat_next,'av_oformat_next',\
av_pkt_dump2,'av_pkt_dump2',\
av_pkt_dump_log2,'av_pkt_dump_log2',\
av_probe_input_buffer,'av_probe_input_buffer',\
av_probe_input_format,'av_probe_input_format',\
av_probe_input_format2,'av_probe_input_format2',\
av_probe_input_format3,'av_probe_input_format3',\
av_read_frame,'av_read_frame',\
av_read_packet,'av_read_packet',\
av_read_pause,'av_read_pause',\
av_read_play,'av_read_play',\
av_register_all,'av_register_all',\
av_register_input_format,'av_register_input_format',\
av_register_output_format,'av_register_output_format',\
av_sdp_create,'av_sdp_create',\
av_seek_frame,'av_seek_frame',\
av_set_pts_info,'av_set_pts_info',\
av_url_split,'av_url_split',\
av_write_frame,'av_write_frame',\
av_write_trailer,'av_write_trailer',\
avformat_alloc_context,'avformat_alloc_context',\
avformat_alloc_output_context,'avformat_alloc_output_context',\
avformat_alloc_output_context2,'avformat_alloc_output_context2',\
avformat_close_input,'avformat_close_input',\
avformat_configuration,'avformat_configuration',\
avformat_find_stream_info,'avformat_find_stream_info',\
avformat_free_context,'avformat_free_context',\
avformat_get_class,'avformat_get_class',\
avformat_get_riff_audio_tags,'avformat_get_riff_audio_tags',\
avformat_get_riff_video_tags,'avformat_get_riff_video_tags',\
avformat_license,'avformat_license',\
avformat_match_stream_specifier,'avformat_match_stream_specifier',\
avformat_network_deinit,'avformat_network_deinit',\
avformat_network_init,'avformat_network_init',\
avformat_new_stream,'avformat_new_stream',\
avformat_open_input,'avformat_open_input',\
avformat_query_codec,'avformat_query_codec',\
avformat_queue_attached_pictures,'avformat_queue_attached_pictures',\
avformat_seek_file,'avformat_seek_file',\
avformat_version,'avformat_version',\
avformat_write_header,'avformat_write_header',\
avio_alloc_context,'avio_alloc_context',\
avio_check,'avio_check',\
avio_close,'avio_close',\
avio_close_dyn_buf,'avio_close_dyn_buf',\
avio_closep,'avio_closep',\
avio_enum_protocols,'avio_enum_protocols',\
avio_flush,'avio_flush',\
avio_get_str,'avio_get_str',\
avio_get_str16be,'avio_get_str16be',\
avio_get_str16le,'avio_get_str16le',\
avio_open,'avio_open',\
avio_open2,'avio_open2',\
avio_open_dyn_buf,'avio_open_dyn_buf',\
avio_pause,'avio_pause',\
avio_printf,'avio_printf',\
avio_put_str,'avio_put_str',\
avio_put_str16le,'avio_put_str16le',\
avio_r8,'avio_r8',\
avio_rb16,'avio_rb16',\
avio_rb24,'avio_rb24',\
avio_rb32,'avio_rb32',\
avio_rb64,'avio_rb64',\
avio_read,'avio_read',\
avio_rl16,'avio_rl16',\
avio_rl24,'avio_rl24',\
avio_rl32,'avio_rl32',\
avio_rl64,'avio_rl64',\
avio_seek,'avio_seek',\
avio_seek_time,'avio_seek_time',\
avio_size,'avio_size',\
avio_skip,'avio_skip',\
avio_w8,'avio_w8',\
avio_wb16,'avio_wb16',\
avio_wb24,'avio_wb24',\
avio_wb32,'avio_wb32',\
avio_wb64,'avio_wb64',\
avio_wl16,'avio_wl16',\
avio_wl24,'avio_wl24',\
avio_wl32,'avio_wl32',\
avio_wl64,'avio_wl64',\
avio_write,'avio_write',\
avpriv_dv_get_packet,'avpriv_dv_get_packet',\
avpriv_dv_init_demux,'avpriv_dv_init_demux',\
avpriv_dv_produce_packet,'avpriv_dv_produce_packet',\
avpriv_new_chapter,'avpriv_new_chapter',\
avpriv_set_pts_info,'avpriv_set_pts_info',\
ff_mpegts_parse_close,'ff_mpegts_parse_close',\
ff_mpegts_parse_open,'ff_mpegts_parse_open',\
ff_mpegts_parse_packet,'ff_mpegts_parse_packet',\
ffio_open_dyn_packet_buf,'ffio_open_dyn_packet_buf',\
ffio_set_buf_size,'ffio_set_buf_size',\
ffurl_close,'ffurl_close',\
ffurl_open,'ffurl_open',\
ffurl_protocol_next,'ffurl_protocol_next',\
ffurl_read_complete,'ffurl_read_complete',\
ffurl_seek,'ffurl_seek',\
ffurl_size,'ffurl_size',\
ffurl_write,'ffurl_write',\
url_feof,'url_feof'

View File

@@ -0,0 +1,286 @@
import avutil-52,\
av_add_q,'av_add_q',\
av_adler32_update,'av_adler32_update',\
av_aes_alloc,'av_aes_alloc',\
av_aes_crypt,'av_aes_crypt',\
av_aes_init,'av_aes_init',\
av_aes_size,'av_aes_size',\
av_asprintf,'av_asprintf',\
av_audio_fifo_alloc,'av_audio_fifo_alloc',\
av_audio_fifo_drain,'av_audio_fifo_drain',\
av_audio_fifo_free,'av_audio_fifo_free',\
av_audio_fifo_read,'av_audio_fifo_read',\
av_audio_fifo_realloc,'av_audio_fifo_realloc',\
av_audio_fifo_reset,'av_audio_fifo_reset',\
av_audio_fifo_size,'av_audio_fifo_size',\
av_audio_fifo_space,'av_audio_fifo_space',\
av_audio_fifo_write,'av_audio_fifo_write',\
av_base64_decode,'av_base64_decode',\
av_base64_encode,'av_base64_encode',\
av_basename,'av_basename',\
av_blowfish_crypt,'av_blowfish_crypt',\
av_blowfish_crypt_ecb,'av_blowfish_crypt_ecb',\
av_blowfish_init,'av_blowfish_init',\
av_bmg_get,'av_bmg_get',\
av_bprint_channel_layout,'av_bprint_channel_layout',\
av_bprint_chars,'av_bprint_chars',\
av_bprint_clear,'av_bprint_clear',\
av_bprint_finalize,'av_bprint_finalize',\
av_bprint_get_buffer,'av_bprint_get_buffer',\
av_bprint_init,'av_bprint_init',\
av_bprint_init_for_buffer,'av_bprint_init_for_buffer',\
av_bprint_strftime,'av_bprint_strftime',\
av_bprintf,'av_bprintf',\
av_calloc,'av_calloc',\
av_channel_layout_extract_channel,'av_channel_layout_extract_channel',\
av_compare_mod,'av_compare_mod',\
av_compare_ts,'av_compare_ts',\
av_crc,'av_crc',\
av_crc_get_table,'av_crc_get_table',\
av_crc_init,'av_crc_init',\
av_ctz,'av_ctz',\
av_d2q,'av_d2q',\
av_d2str,'av_d2str',\
av_dbl2ext,'av_dbl2ext',\
av_dbl2int,'av_dbl2int',\
av_default_get_category,'av_default_get_category',\
av_default_item_name,'av_default_item_name',\
av_des_crypt,'av_des_crypt',\
av_des_init,'av_des_init',\
av_des_mac,'av_des_mac',\
av_dict_copy,'av_dict_copy',\
av_dict_count,'av_dict_count',\
av_dict_free,'av_dict_free',\
av_dict_get,'av_dict_get',\
av_dict_set,'av_dict_set',\
av_dirname,'av_dirname',\
av_div_q,'av_div_q',\
av_dynarray_add,'av_dynarray_add',\
av_evaluate_lls,'av_evaluate_lls',\
av_expr_eval,'av_expr_eval',\
av_expr_free,'av_expr_free',\
av_expr_parse,'av_expr_parse',\
av_expr_parse_and_eval,'av_expr_parse_and_eval',\
av_ext2dbl,'av_ext2dbl',\
av_fifo_alloc,'av_fifo_alloc',\
av_fifo_drain,'av_fifo_drain',\
av_fifo_free,'av_fifo_free',\
av_fifo_generic_read,'av_fifo_generic_read',\
av_fifo_generic_write,'av_fifo_generic_write',\
av_fifo_grow,'av_fifo_grow',\
av_fifo_realloc2,'av_fifo_realloc2',\
av_fifo_reset,'av_fifo_reset',\
av_fifo_size,'av_fifo_size',\
av_fifo_space,'av_fifo_space',\
av_file_map,'av_file_map',\
av_file_unmap,'av_file_unmap',\
av_find_info_tag,'av_find_info_tag',\
av_find_nearest_q_idx,'av_find_nearest_q_idx',\
av_find_opt,'av_find_opt',\
av_flt2int,'av_flt2int',\
av_force_cpu_flags,'av_force_cpu_flags',\
av_free,'av_free',\
av_freep,'av_freep',\
av_gcd,'av_gcd',\
av_get_alt_sample_fmt,'av_get_alt_sample_fmt',\
av_get_bits_per_pixel,'av_get_bits_per_pixel',\
av_get_bits_per_sample_fmt,'av_get_bits_per_sample_fmt',\
av_get_bytes_per_sample,'av_get_bytes_per_sample',\
av_get_channel_description,'av_get_channel_description',\
av_get_channel_layout,'av_get_channel_layout',\
av_get_channel_layout_channel_index,'av_get_channel_layout_channel_index',\
av_get_channel_layout_nb_channels,'av_get_channel_layout_nb_channels',\
av_get_channel_layout_string,'av_get_channel_layout_string',\
av_get_channel_name,'av_get_channel_name',\
av_get_cpu_flags,'av_get_cpu_flags',\
av_get_default_channel_layout,'av_get_default_channel_layout',\
av_get_double,'av_get_double',\
av_get_int,'av_get_int',\
av_get_media_type_string,'av_get_media_type_string',\
av_get_packed_sample_fmt,'av_get_packed_sample_fmt',\
av_get_padded_bits_per_pixel,'av_get_padded_bits_per_pixel',\
av_get_picture_type_char,'av_get_picture_type_char',\
av_get_pix_fmt,'av_get_pix_fmt',\
av_get_pix_fmt_name,'av_get_pix_fmt_name',\
av_get_pix_fmt_string,'av_get_pix_fmt_string',\
av_get_planar_sample_fmt,'av_get_planar_sample_fmt',\
av_get_q,'av_get_q',\
av_get_random_seed,'av_get_random_seed',\
av_get_sample_fmt,'av_get_sample_fmt',\
av_get_sample_fmt_name,'av_get_sample_fmt_name',\
av_get_sample_fmt_string,'av_get_sample_fmt_string',\
av_get_standard_channel_layout,'av_get_standard_channel_layout',\
av_get_string,'av_get_string',\
av_get_token,'av_get_token',\
av_gettime,'av_gettime',\
av_image_alloc,'av_image_alloc',\
av_image_check_size,'av_image_check_size',\
av_image_copy,'av_image_copy',\
av_image_copy_plane,'av_image_copy_plane',\
av_image_copy_to_buffer,'av_image_copy_to_buffer',\
av_image_fill_arrays,'av_image_fill_arrays',\
av_image_fill_linesizes,'av_image_fill_linesizes',\
av_image_fill_max_pixsteps,'av_image_fill_max_pixsteps',\
av_image_fill_pointers,'av_image_fill_pointers',\
av_image_get_buffer_size,'av_image_get_buffer_size',\
av_image_get_linesize,'av_image_get_linesize',\
av_init_lls,'av_init_lls',\
av_int2dbl,'av_int2dbl',\
av_int2flt,'av_int2flt',\
av_lfg_init,'av_lfg_init',\
av_log,'av_log',\
av_log2,'av_log2',\
av_log2_16bit,'av_log2_16bit',\
av_log_default_callback,'av_log_default_callback',\
av_log_format_line,'av_log_format_line',\
av_log_get_level,'av_log_get_level',\
av_log_set_callback,'av_log_set_callback',\
av_log_set_flags,'av_log_set_flags',\
av_log_set_level,'av_log_set_level',\
av_lzo1x_decode,'av_lzo1x_decode',\
av_malloc,'av_malloc',\
av_mallocz,'av_mallocz',\
av_max_alloc,'av_max_alloc',\
av_md5_alloc,'av_md5_alloc',\
av_md5_final,'av_md5_final',\
av_md5_init,'av_md5_init',\
av_md5_size,'av_md5_size',\
av_md5_sum,'av_md5_sum',\
av_md5_update,'av_md5_update',\
av_memcpy_backptr,'av_memcpy_backptr',\
av_mul_q,'av_mul_q',\
av_nearer_q,'av_nearer_q',\
av_next_option,'av_next_option',\
av_opt_child_class_next,'av_opt_child_class_next',\
av_opt_child_next,'av_opt_child_next',\
av_opt_eval_double,'av_opt_eval_double',\
av_opt_eval_flags,'av_opt_eval_flags',\
av_opt_eval_float,'av_opt_eval_float',\
av_opt_eval_int,'av_opt_eval_int',\
av_opt_eval_int64,'av_opt_eval_int64',\
av_opt_eval_q,'av_opt_eval_q',\
av_opt_find,'av_opt_find',\
av_opt_find2,'av_opt_find2',\
av_opt_flag_is_set,'av_opt_flag_is_set',\
av_opt_free,'av_opt_free',\
av_opt_freep_ranges,'av_opt_freep_ranges',\
av_opt_get,'av_opt_get',\
av_opt_get_double,'av_opt_get_double',\
av_opt_get_image_size,'av_opt_get_image_size',\
av_opt_get_int,'av_opt_get_int',\
av_opt_get_key_value,'av_opt_get_key_value',\
av_opt_get_pixel_fmt,'av_opt_get_pixel_fmt',\
av_opt_get_q,'av_opt_get_q',\
av_opt_get_sample_fmt,'av_opt_get_sample_fmt',\
av_opt_next,'av_opt_next',\
av_opt_ptr,'av_opt_ptr',\
av_opt_query_ranges,'av_opt_query_ranges',\
av_opt_query_ranges_default,'av_opt_query_ranges_default',\
av_opt_set,'av_opt_set',\
av_opt_set_bin,'av_opt_set_bin',\
av_opt_set_defaults,'av_opt_set_defaults',\
av_opt_set_defaults2,'av_opt_set_defaults2',\
av_opt_set_dict,'av_opt_set_dict',\
av_opt_set_double,'av_opt_set_double',\
av_opt_set_from_string,'av_opt_set_from_string',\
av_opt_set_image_size,'av_opt_set_image_size',\
av_opt_set_int,'av_opt_set_int',\
av_opt_set_pixel_fmt,'av_opt_set_pixel_fmt',\
av_opt_set_q,'av_opt_set_q',\
av_opt_set_sample_fmt,'av_opt_set_sample_fmt',\
av_opt_show2,'av_opt_show2',\
av_parse_color,'av_parse_color',\
av_parse_cpu_caps,'av_parse_cpu_caps',\
av_parse_cpu_flags,'av_parse_cpu_flags',\
av_parse_ratio,'av_parse_ratio',\
av_parse_time,'av_parse_time',\
av_parse_video_rate,'av_parse_video_rate',\
av_parse_video_size,'av_parse_video_size',\
av_pix_fmt_desc_get,'av_pix_fmt_desc_get',\
av_pix_fmt_desc_get_id,'av_pix_fmt_desc_get_id',\
av_pix_fmt_desc_next,'av_pix_fmt_desc_next',\
av_pix_fmt_descriptors,'av_pix_fmt_descriptors',\
av_pix_fmt_get_chroma_sub_sample,'av_pix_fmt_get_chroma_sub_sample',\
av_rc4_crypt,'av_rc4_crypt',\
av_rc4_init,'av_rc4_init',\
av_read_image_line,'av_read_image_line',\
av_realloc,'av_realloc',\
av_realloc_f,'av_realloc_f',\
av_reduce,'av_reduce',\
av_rescale,'av_rescale',\
av_rescale_delta,'av_rescale_delta',\
av_rescale_q,'av_rescale_q',\
av_rescale_q_rnd,'av_rescale_q_rnd',\
av_rescale_rnd,'av_rescale_rnd',\
av_reverse,'av_reverse',\
av_sample_fmt_is_planar,'av_sample_fmt_is_planar',\
av_samples_alloc,'av_samples_alloc',\
av_samples_copy,'av_samples_copy',\
av_samples_fill_arrays,'av_samples_fill_arrays',\
av_samples_get_buffer_size,'av_samples_get_buffer_size',\
av_samples_set_silence,'av_samples_set_silence',\
av_set_cpu_flags_mask,'av_set_cpu_flags_mask',\
av_set_double,'av_set_double',\
av_set_int,'av_set_int',\
av_set_options_string,'av_set_options_string',\
av_set_q,'av_set_q',\
av_set_string3,'av_set_string3',\
av_sha_alloc,'av_sha_alloc',\
av_sha_final,'av_sha_final',\
av_sha_init,'av_sha_init',\
av_sha_size,'av_sha_size',\
av_sha_update,'av_sha_update',\
av_small_strptime,'av_small_strptime',\
av_solve_lls,'av_solve_lls',\
av_strcasecmp,'av_strcasecmp',\
av_strdup,'av_strdup',\
av_strerror,'av_strerror',\
av_stristart,'av_stristart',\
av_stristr,'av_stristr',\
av_strlcat,'av_strlcat',\
av_strlcatf,'av_strlcatf',\
av_strlcpy,'av_strlcpy',\
av_strncasecmp,'av_strncasecmp',\
av_strstart,'av_strstart',\
av_strtod,'av_strtod',\
av_strtok,'av_strtok',\
av_sub_q,'av_sub_q',\
av_tempfile,'av_tempfile',\
av_timecode_adjust_ntsc_framenum2,'av_timecode_adjust_ntsc_framenum2',\
av_timecode_check_frame_rate,'av_timecode_check_frame_rate',\
av_timecode_get_smpte_from_framenum,'av_timecode_get_smpte_from_framenum',\
av_timecode_init,'av_timecode_init',\
av_timecode_init_from_string,'av_timecode_init_from_string',\
av_timecode_make_mpeg_tc_string,'av_timecode_make_mpeg_tc_string',\
av_timecode_make_smpte_tc_string,'av_timecode_make_smpte_tc_string',\
av_timecode_make_string,'av_timecode_make_string',\
av_timegm,'av_timegm',\
av_tree_destroy,'av_tree_destroy',\
av_tree_enumerate,'av_tree_enumerate',\
av_tree_find,'av_tree_find',\
av_tree_insert,'av_tree_insert',\
av_tree_node_alloc,'av_tree_node_alloc',\
av_tree_node_size,'av_tree_node_size',\
av_update_lls,'av_update_lls',\
av_usleep,'av_usleep',\
av_vlog,'av_vlog',\
av_write_image_line,'av_write_image_line',\
av_xtea_crypt,'av_xtea_crypt',\
av_xtea_init,'av_xtea_init',\
avpriv_cga_font,'avpriv_cga_font',\
avpriv_float_dsp_init,'avpriv_float_dsp_init',\
avpriv_set_systematic_pal2,'avpriv_set_systematic_pal2',\
avpriv_vga16_font,'avpriv_vga16_font',\
avutil_configuration,'avutil_configuration',\
avutil_license,'avutil_license',\
avutil_version,'avutil_version',\
ff_cpu_cpuid,'ff_cpu_cpuid',\
ff_cpu_cpuid_test,'ff_cpu_cpuid_test',\
ff_cpu_xgetbv,'ff_cpu_xgetbv',\
ff_float_dsp_init_x86,'ff_float_dsp_init_x86',\
ff_get_cpu_flags_x86,'ff_get_cpu_flags_x86',\
ff_log2_tab,'ff_log2_tab',\
ff_vector_dmul_scalar_sse2,'ff_vector_dmul_scalar_sse2',\
ff_vector_fmac_scalar_sse,'ff_vector_fmac_scalar_sse',\
ff_vector_fmul_scalar_sse,'ff_vector_fmul_scalar_sse',\
ff_vector_fmul_sse,'ff_vector_fmul_sse'

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
; Macroinstructions for making import section
macro library [name,string]
{ common
import.data:
forward
local _label
if defined name#.redundant
if ~ name#.redundant
dd name#.lookup,0,0, _label, name#.address
end if
end if
name#.referred = 1
common
dd 0,0,0,0,0
forward
if defined name#.redundant
if ~ name#.redundant
_label db string,0
rb $ and 1
end if
end if }
macro import name,[label,string]
{ common
rb (- $) and 3
if defined name#.referred
name#.lookup:
forward
if used label
if string eqtype ''
local _label
dd _label
else
dd 80000000h + string
end if
end if
common
if $ > name#.lookup
name#.redundant = 0
dd 0
else
name#.redundant = 1
end if
name#.address:
forward
if used label
if string eqtype ''
label dd _label
else
label dd 80000000h + string
end if
end if
common
if ~ name#.redundant
dd 0
end if
forward
if used label & string eqtype ''
_label dw 0
db string,0
rb $ and 1
end if
common
end if }
macro api [name] {}

View File

@@ -0,0 +1,674 @@
import libc,\
__Balloc,'_Balloc',\
__Bfree,'_Bfree',\
__Exit,'_Exit',\
___ChkTTYIOMode,'__ChkTTYIOMode',\
___GetIOMode,'__GetIOMode',\
___SetIOMode,'__SetIOMode',\
___SetIOMode_nogrow,'__SetIOMode_nogrow',\
___allocPOSIXHandle,'__allocPOSIXHandle',\
___any_on,'__any_on',\
___ascii_mbtowc,'__ascii_mbtowc',\
___ascii_wctomb,'__ascii_wctomb',\
___assert_func,'__assert_func',\
___b2d,'__b2d',\
___call_exitprocs,'__call_exitprocs',\
___copybits,'__copybits',\
___cpu_features_init,'__cpu_features_init',\
___ctype_load_locale,'__ctype_load_locale',\
___ctype_ptr__,'__ctype_ptr__',\
___d2b,'__d2b',\
___dorand48,'__dorand48',\
___dtoa,'__dtoa',\
___emutls_get_address,'__emutls_get_address',\
___emutls_register_common,'__emutls_register_common',\
___errno,'__errno',\
___fp_lock_all,'__fp_lock_all',\
___fp_unlock_all,'__fp_unlock_all',\
___fpclassifyd,'__fpclassifyd',\
___fpclassifyf,'__fpclassifyf',\
___freePOSIXHandle,'__freePOSIXHandle',\
___getOSHandle,'__getOSHandle',\
___get_current_ctype_locale,'__get_current_ctype_locale',\
___gethex,'__gethex',\
___gettzinfo,'__gettzinfo',\
___growPOSIXHandles,'__growPOSIXHandles',\
___grow_iomode,'__grow_iomode',\
___gthread_once,'__gthread_once',\
___hexdig_init,'__hexdig_init',\
___hexnan,'__hexnan',\
___hi0bits,'__hi0bits',\
___i2b,'__i2b',\
___ieee754_acos,'__ieee754_acos',\
___ieee754_acosf,'__ieee754_acosf',\
___ieee754_acosh,'__ieee754_acosh',\
___ieee754_acoshf,'__ieee754_acoshf',\
___ieee754_asin,'__ieee754_asin',\
___ieee754_asinf,'__ieee754_asinf',\
___ieee754_atan2,'__ieee754_atan2',\
___ieee754_atan2f,'__ieee754_atan2f',\
___ieee754_atanh,'__ieee754_atanh',\
___ieee754_atanhf,'__ieee754_atanhf',\
___ieee754_cosh,'__ieee754_cosh',\
___ieee754_coshf,'__ieee754_coshf',\
___ieee754_exp,'__ieee754_exp',\
___ieee754_expf,'__ieee754_expf',\
___ieee754_fmod,'__ieee754_fmod',\
___ieee754_fmodf,'__ieee754_fmodf',\
___ieee754_gamma_r,'__ieee754_gamma_r',\
___ieee754_gammaf_r,'__ieee754_gammaf_r',\
___ieee754_hypot,'__ieee754_hypot',\
___ieee754_hypotf,'__ieee754_hypotf',\
___ieee754_j0,'__ieee754_j0',\
___ieee754_j0f,'__ieee754_j0f',\
___ieee754_j1,'__ieee754_j1',\
___ieee754_j1f,'__ieee754_j1f',\
___ieee754_jn,'__ieee754_jn',\
___ieee754_jnf,'__ieee754_jnf',\
___ieee754_lgamma_r,'__ieee754_lgamma_r',\
___ieee754_lgammaf_r,'__ieee754_lgammaf_r',\
___ieee754_log,'__ieee754_log',\
___ieee754_log10,'__ieee754_log10',\
___ieee754_log10f,'__ieee754_log10f',\
___ieee754_logf,'__ieee754_logf',\
___ieee754_pow,'__ieee754_pow',\
___ieee754_powf,'__ieee754_powf',\
___ieee754_rem_pio2,'__ieee754_rem_pio2',\
___ieee754_rem_pio2f,'__ieee754_rem_pio2f',\
___ieee754_remainder,'__ieee754_remainder',\
___ieee754_remainderf,'__ieee754_remainderf',\
___ieee754_scalb,'__ieee754_scalb',\
___ieee754_scalbf,'__ieee754_scalbf',\
___ieee754_sinh,'__ieee754_sinh',\
___ieee754_sinhf,'__ieee754_sinhf',\
___ieee754_sqrt,'__ieee754_sqrt',\
___ieee754_sqrtf,'__ieee754_sqrtf',\
___ieee754_y0,'__ieee754_y0',\
___ieee754_y0f,'__ieee754_y0f',\
___ieee754_y1,'__ieee754_y1',\
___ieee754_y1f,'__ieee754_y1f',\
___ieee754_yn,'__ieee754_yn',\
___ieee754_ynf,'__ieee754_ynf',\
___infinity,'__infinity',\
___infinityf,'__infinityf',\
___infinityld,'__infinityld',\
___init_mode,'__init_mode',\
___io_mode,'__io_mode',\
___isinfd,'__isinfd',\
___isinff,'__isinff',\
___isnand,'__isnand',\
___isnanf,'__isnanf',\
___kernel_cos,'__kernel_cos',\
___kernel_cosf,'__kernel_cosf',\
___kernel_rem_pio2,'__kernel_rem_pio2',\
___kernel_rem_pio2f,'__kernel_rem_pio2f',\
___kernel_sin,'__kernel_sin',\
___kernel_sinf,'__kernel_sinf',\
___kernel_standard,'__kernel_standard',\
___kernel_tan,'__kernel_tan',\
___kernel_tanf,'__kernel_tanf',\
___libc_getenv,'__libc_getenv',\
___lo0bits,'__lo0bits',\
___locale_charset,'__locale_charset',\
___locale_cjk_lang,'__locale_cjk_lang',\
___locale_mb_cur_max,'__locale_mb_cur_max',\
___locale_msgcharset,'__locale_msgcharset',\
___lshift,'__lshift',\
___malloc_lock,'__malloc_lock',\
___malloc_unlock,'__malloc_unlock',\
___mb_cur_max,'__mb_cur_max',\
___mbtowc,'__mbtowc',\
___mcmp,'__mcmp',\
___mdiff,'__mdiff',\
___mlocale_changed,'__mlocale_changed',\
___mprec_bigtens,'__mprec_bigtens',\
___mprec_tens,'__mprec_tens',\
___mprec_tinytens,'__mprec_tinytens',\
___multadd,'__multadd',\
___multiply,'__multiply',\
___mutex_lock,'__mutex_lock',\
___nlocale_changed,'__nlocale_changed',\
___pow5mult,'__pow5mult',\
___ratio,'__ratio',\
___register_exitproc,'__register_exitproc',\
___s2b,'__s2b',\
___sccl,'__sccl',\
___sclose,'__sclose',\
___seofread,'__seofread',\
___setOSHandle,'__setOSHandle',\
___set_handles,'__set_handles',\
___sflags,'__sflags',\
___sflush_r,'__sflush_r',\
___sfmoreglue,'__sfmoreglue',\
___sfp,'__sfp',\
___sfp_lock_acquire,'__sfp_lock_acquire',\
___sfp_lock_release,'__sfp_lock_release',\
___sfvwrite_r,'__sfvwrite_r',\
___shrink_iomode,'__shrink_iomode',\
___signbitd,'__signbitd',\
___signbitf,'__signbitf',\
___sigtramp,'__sigtramp',\
___sigtramp_r,'__sigtramp_r',\
___sinit,'__sinit',\
___sinit_lock_acquire,'__sinit_lock_acquire',\
___sinit_lock_release,'__sinit_lock_release',\
___smakebuf_r,'__smakebuf_r',\
___sprint_r,'__sprint_r',\
___sread,'__sread',\
___srefill_r,'__srefill_r',\
___srget,'__srget',\
___srget_r,'__srget_r',\
___sseek,'__sseek',\
___ssprint_r,'__ssprint_r',\
___ssrefill_r,'__ssrefill_r',\
___ssvfiscanf_r,'__ssvfiscanf_r',\
___ssvfscanf_r,'__ssvfscanf_r',\
___strtok_r,'__strtok_r',\
___submore,'__submore',\
___svfiscanf,'__svfiscanf',\
___svfiscanf_r,'__svfiscanf_r',\
___svfscanf,'__svfscanf',\
___svfscanf_r,'__svfscanf_r',\
___swbuf,'__swbuf',\
___swbuf_r,'__swbuf_r',\
___swrite,'__swrite',\
___swsetup_r,'__swsetup_r',\
___thread_startup,'__thread_startup',\
___tz_lock,'__tz_lock',\
___tz_unlock,'__tz_unlock',\
___tzcalc_limits,'__tzcalc_limits',\
___ulp,'__ulp',\
___wctomb,'__wctomb',\
__assert,'_assert',\
__atoi_r,'_atoi_r',\
__atol_r,'_atol_r',\
__buf_findstr,'_buf_findstr',\
__calloc_r,'_calloc_r',\
__cleanup,'_cleanup',\
__cleanup_r,'_cleanup_r',\
__close_r,'_close_r',\
__ctype_,'_ctype_',\
__daylight,'_daylight',\
__diprintf_r,'_diprintf_r',\
__dprintf_r,'_dprintf_r',\
__dtoa_r,'_dtoa_r',\
__exit,'_exit',\
__f_atan2,'_f_atan2',\
__f_atan2f,'_f_atan2f',\
__f_exp,'_f_exp',\
__f_expf,'_f_expf',\
__f_frexp,'_f_frexp',\
__f_frexpf,'_f_frexpf',\
__f_ldexp,'_f_ldexp',\
__f_ldexpf,'_f_ldexpf',\
__f_llrint,'_f_llrint',\
__f_llrintf,'_f_llrintf',\
__f_llrintl,'_f_llrintl',\
__f_log,'_f_log',\
__f_log10,'_f_log10',\
__f_log10f,'_f_log10f',\
__f_logf,'_f_logf',\
__f_lrint,'_f_lrint',\
__f_lrintf,'_f_lrintf',\
__f_lrintl,'_f_lrintl',\
__f_pow,'_f_pow',\
__f_powf,'_f_powf',\
__f_rint,'_f_rint',\
__f_rintf,'_f_rintf',\
__f_rintl,'_f_rintl',\
__f_tan,'_f_tan',\
__f_tanf,'_f_tanf',\
__fclose_r,'_fclose_r',\
__fdopen_r,'_fdopen_r',\
__fflush_r,'_fflush_r',\
__fgetc_r,'_fgetc_r',\
__fgets_r,'_fgets_r',\
__findenv,'_findenv',\
__fiprintf_r,'_fiprintf_r',\
__fiscanf_r,'_fiscanf_r',\
__fopen_r,'_fopen_r',\
__fprintf_r,'_fprintf_r',\
__fputc_r,'_fputc_r',\
__fputs_r,'_fputs_r',\
__fputwc_r,'_fputwc_r',\
__fread_r,'_fread_r',\
__free_r,'_free_r',\
__freopen_r,'_freopen_r',\
__fscanf_r,'_fscanf_r',\
__fseek_r,'_fseek_r',\
__fseeko_r,'_fseeko_r',\
__fstat_r,'_fstat_r',\
__ftell_r,'_ftell_r',\
__ftello_r,'_ftello_r',\
__fwalk,'_fwalk',\
__fwalk_reent,'_fwalk_reent',\
__fwrite_r,'_fwrite_r',\
__gettimeofday,'_gettimeofday',\
__gettimeofday_r,'_gettimeofday_r',\
__global_impure_ptr,'_global_impure_ptr',\
__grow_handles,'_grow_handles',\
__init_signal,'_init_signal',\
__init_signal_r,'_init_signal_r',\
__isatty,'_isatty',\
__isatty_r,'_isatty_r',\
__kill_r,'_kill_r',\
__localeconv_r,'_localeconv_r',\
__lseek_r,'_lseek_r',\
__malloc_r,'_malloc_r',\
__mbrtowc_r,'_mbrtowc_r',\
__mbtowc_r,'_mbtowc_r',\
__mktm_r,'_mktm_r',\
__mprec_log10,'_mprec_log10',\
__open_r,'_open_r',\
__printf_r,'_printf_r',\
__putc_r,'_putc_r',\
__putchar_r,'_putchar_r',\
__puts_r,'_puts_r',\
__raise_r,'_raise_r',\
__read,'_read',\
__read_r,'_read_r',\
__realloc_r,'_realloc_r',\
__remove_r,'_remove_r',\
__rename_r,'_rename_r',\
__seed48_r,'_seed48_r',\
__setlocale_r,'_setlocale_r',\
__sfread_r,'_sfread_r',\
__signal_r,'_signal_r',\
__siprintf_r,'_siprintf_r',\
__sniprintf_r,'_sniprintf_r',\
__snprintf_r,'_snprintf_r',\
__sprintf_r,'_sprintf_r',\
__srand48_r,'_srand48_r',\
__sscanf_r,'_sscanf_r',\
__strdup_r,'_strdup_r',\
__strerror_r,'_strerror_r',\
__strndup_r,'_strndup_r',\
__strtod_r,'_strtod_r',\
__strtol_r,'_strtol_r',\
__strtoll_r,'_strtoll_r',\
__strtoul_r,'_strtoul_r',\
__strtoull_r,'_strtoull_r',\
__sungetc_r,'_sungetc_r',\
__svfiprintf_r,'_svfiprintf_r',\
__svfprintf_r,'_svfprintf_r',\
__system_r,'_system_r',\
__tempnam_r,'_tempnam_r',\
__times_r,'_times_r',\
__timezone,'_timezone',\
__tls_map,'_tls_map',\
__tmpfile_r,'_tmpfile_r',\
__tmpnam_r,'_tmpnam_r',\
__towctrans_r,'_towctrans_r',\
__tzname,'_tzname',\
__ungetc_r,'_ungetc_r',\
__user_strerror,'_user_strerror',\
__vasniprintf_r,'_vasniprintf_r',\
__vasnprintf_r,'_vasnprintf_r',\
__vdiprintf_r,'_vdiprintf_r',\
__vdprintf_r,'_vdprintf_r',\
__vfiprintf_r,'_vfiprintf_r',\
__vfiscanf_r,'_vfiscanf_r',\
__vfprintf_r,'_vfprintf_r',\
__vfscanf_r,'_vfscanf_r',\
__vscanf_r,'_vscanf_r',\
__vsnprintf_r,'_vsnprintf_r',\
__vsprintf_r,'_vsprintf_r',\
__vsscanf_r,'_vsscanf_r',\
__wcrtomb_r,'_wcrtomb_r',\
__wctomb_r,'_wctomb_r',\
__wctrans_r,'_wctrans_r',\
__wctype_r,'_wctype_r',\
__write_r,'_write_r',\
_abort,'abort',\
_abs,'abs',\
_acos,'acos',\
_acosf,'acosf',\
_acosh,'acosh',\
_acoshf,'acoshf',\
_asctime,'asctime',\
_asctime_r,'asctime_r',\
_asin,'asin',\
_asinf,'asinf',\
_asinh,'asinh',\
_asinhf,'asinhf',\
_atan,'atan',\
_atan2,'atan2',\
_atan2f,'atan2f',\
_atanf,'atanf',\
_atanh,'atanh',\
_atanhf,'atanhf',\
_atof,'atof',\
_atoi,'atoi',\
_atol,'atol',\
_bsearch,'bsearch',\
_calloc,'calloc',\
_cbrt,'cbrt',\
_cbrtf,'cbrtf',\
_ceil,'ceil',\
_ceilf,'ceilf',\
_clearerr,'clearerr',\
_clock,'clock',\
_close,'close',\
_copysign,'copysign',\
_copysignf,'copysignf',\
_cos,'cos',\
_cosf,'cosf',\
_cosh,'cosh',\
_coshf,'coshf',\
_create_file,'create_file',\
_create_image,'create_image',\
_create_thread,'create_thread',\
_ctime,'ctime',\
_ctime_r,'ctime_r',\
_debugwrite,'debugwrite',\
_delete_file,'delete_file',\
_difftime,'difftime',\
_diprintf,'diprintf',\
_div,'div',\
_dprintf,'dprintf',\
_drem,'drem',\
_dremf,'dremf',\
_entry,'entry',\
_envz_get,'envz_get',\
_erf,'erf',\
_erfc,'erfc',\
_erfcf,'erfcf',\
_erff,'erff',\
_exit,'exit',\
_exp,'exp',\
_exp10,'exp10',\
_exp10f,'exp10f',\
_exp2,'exp2',\
_exp2f,'exp2f',\
_expf,'expf',\
_expm1,'expm1',\
_expm1f,'expm1f',\
_fabs,'fabs',\
_fabsf,'fabsf',\
_fclose,'fclose',\
_fdim,'fdim',\
_fdimf,'fdimf',\
_fdopen,'fdopen',\
_fflush,'fflush',\
_fgetc,'fgetc',\
_fgets,'fgets',\
_fileno,'fileno',\
_finite,'finite',\
_finitef,'finitef',\
_fiprintf,'fiprintf',\
_fiscanf,'fiscanf',\
_floor,'floor',\
_floorf,'floorf',\
_fma,'fma',\
_fmaf,'fmaf',\
_fmax,'fmax',\
_fmaxf,'fmaxf',\
_fmin,'fmin',\
_fminf,'fminf',\
_fmod,'fmod',\
_fmodf,'fmodf',\
_fopen,'fopen',\
_fprintf,'fprintf',\
_fputc,'fputc',\
_fputs,'fputs',\
_fputwc,'fputwc',\
_fread,'fread',\
_free,'free',\
_freopen,'freopen',\
_frexp,'frexp',\
_frexpf,'frexpf',\
_fscanf,'fscanf',\
_fseek,'fseek',\
_fseeko,'fseeko',\
_fstat,'fstat',\
_ftell,'ftell',\
_ftello,'ftello',\
_fwrite,'fwrite',\
_gamma,'gamma',\
_gamma_r,'gamma_r',\
_gammaf,'gammaf',\
_gammaf_r,'gammaf_r',\
_get_entry_point,'get_entry_point',\
_get_fileinfo,'get_fileinfo',\
_get_proc_address,'get_proc_address',\
_getenv,'getenv',\
_gettimeofday,'gettimeofday',\
_gmtime,'gmtime',\
_gmtime_r,'gmtime_r',\
_hypot,'hypot',\
_hypotf,'hypotf',\
_ilogb,'ilogb',\
_ilogbf,'ilogbf',\
_infinity,'infinity',\
_infinityf,'infinityf',\
_init_global_reent,'init_global_reent',\
_init_loader,'init_loader',\
_init_reent,'init_reent',\
_isalnum,'isalnum',\
_isalpha,'isalpha',\
_isascii,'isascii',\
_isblank,'isblank',\
_iscntrl,'iscntrl',\
_isdigit,'isdigit',\
_isgraph,'isgraph',\
_isinf,'isinf',\
_isinff,'isinff',\
_islower,'islower',\
_isnan,'isnan',\
_isnanf,'isnanf',\
_isprint,'isprint',\
_ispunct,'ispunct',\
_isspace,'isspace',\
_isupper,'isupper',\
_iswalnum,'iswalnum',\
_iswalpha,'iswalpha',\
_iswblank,'iswblank',\
_iswcntrl,'iswcntrl',\
_iswctype,'iswctype',\
_iswdigit,'iswdigit',\
_iswgraph,'iswgraph',\
_iswlower,'iswlower',\
_iswprint,'iswprint',\
_iswpunct,'iswpunct',\
_iswspace,'iswspace',\
_iswupper,'iswupper',\
_iswxdigit,'iswxdigit',\
_isxdigit,'isxdigit',\
_j0,'j0',\
_j0f,'j0f',\
_j1,'j1',\
_j1f,'j1f',\
_jn,'jn',\
_jnf,'jnf',\
_ldexp,'ldexp',\
_ldexpf,'ldexpf',\
_lgamma,'lgamma',\
_lgamma_r,'lgamma_r',\
_lgammaf,'lgammaf',\
_lgammaf_r,'lgammaf_r',\
_libc_crt_startup,'libc_crt_startup',\
_link_app,'link_app',\
_link_image,'link_image',\
_llrint,'llrint',\
_llrintf,'llrintf',\
_llrintl,'llrintl',\
_llround,'llround',\
_llroundf,'llroundf',\
_load_library,'load_library',\
_loader_env,'loader_env',\
_localeconv,'localeconv',\
_localtime,'localtime',\
_localtime_r,'localtime_r',\
_log,'log',\
_log10,'log10',\
_log10f,'log10f',\
_log1p,'log1p',\
_log1pf,'log1pf',\
_log2,'log2',\
_log2f,'log2f',\
_logb,'logb',\
_logbf,'logbf',\
_logf,'logf',\
_longjmp,'longjmp',\
_lrint,'lrint',\
_lrintf,'lrintf',\
_lrintl,'lrintl',\
_lround,'lround',\
_lroundf,'lroundf',\
_lseek,'lseek',\
_malloc,'malloc',\
_matherr,'matherr',\
_mbrtowc,'mbrtowc',\
_mbtowc,'mbtowc',\
_memalign,'memalign',\
_memchr,'memchr',\
_memcmp,'memcmp',\
_memcpy,'memcpy',\
_memmove,'memmove',\
_memset,'memset',\
_mktime,'mktime',\
_modf,'modf',\
_modff,'modff',\
_nan,'nan',\
_nanf,'nanf',\
_nearbyint,'nearbyint',\
_nearbyintf,'nearbyintf',\
_nextafter,'nextafter',\
_nextafterf,'nextafterf',\
_open,'open',\
_path_list,'path_list',\
_pow,'pow',\
_pow10,'pow10',\
_pow10f,'pow10f',\
_powf,'powf',\
_printf,'printf',\
_putc,'putc',\
_putchar,'putchar',\
_puts,'puts',\
_qsort,'qsort',\
_raise,'raise',\
_rand,'rand',\
_rand_r,'rand_r',\
_read,'read',\
_read_file,'read_file',\
_realloc,'realloc',\
_remainder,'remainder',\
_remainderf,'remainderf',\
_remove,'remove',\
_remquo,'remquo',\
_remquof,'remquof',\
_rename,'rename',\
_rint,'rint',\
_rintf,'rintf',\
_rintl,'rintl',\
_round,'round',\
_roundf,'roundf',\
_scalb,'scalb',\
_scalbf,'scalbf',\
_scalbln,'scalbln',\
_scalblnf,'scalblnf',\
_scalbn,'scalbn',\
_scalbnf,'scalbnf',\
_seed48,'seed48',\
_set_file_size,'set_file_size',\
_setjmp,'setjmp',\
_setlocale,'setlocale',\
_setvbuf,'setvbuf',\
_signal,'signal',\
_significand,'significand',\
_significandf,'significandf',\
_sin,'sin',\
_sincos,'sincos',\
_sincosf,'sincosf',\
_sinf,'sinf',\
_sinh,'sinh',\
_sinhf,'sinhf',\
_siprintf,'siprintf',\
_sniprintf,'sniprintf',\
_snprintf,'snprintf',\
_sprintf,'sprintf',\
_sqrt,'sqrt',\
_sqrtf,'sqrtf',\
_srand,'srand',\
_srand48,'srand48',\
_sscanf,'sscanf',\
_stpcpy,'stpcpy',\
_stpncpy,'stpncpy',\
_strcasecmp,'strcasecmp',\
_strcasestr,'strcasestr',\
_strcat,'strcat',\
_strchr,'strchr',\
_strcmp,'strcmp',\
_strcoll,'strcoll',\
_strcpy,'strcpy',\
_strcspn,'strcspn',\
_strdup,'strdup',\
_strerror,'strerror',\
_strftime,'strftime',\
_strlen,'strlen',\
_strncasecmp,'strncasecmp',\
_strncat,'strncat',\
_strncmp,'strncmp',\
_strncpy,'strncpy',\
_strndup,'strndup',\
_strnlen,'strnlen',\
_strpbrk,'strpbrk',\
_strrchr,'strrchr',\
_strsep,'strsep',\
_strspn,'strspn',\
_strstr,'strstr',\
_strtod,'strtod',\
_strtof,'strtof',\
_strtok,'strtok',\
_strtok_r,'strtok_r',\
_strtol,'strtol',\
_strtoll,'strtoll',\
_strtoul,'strtoul',\
_strtoull,'strtoull',\
_strupr,'strupr',\
_system,'system',\
_tan,'tan',\
_tanf,'tanf',\
_tanh,'tanh',\
_tanhf,'tanhf',\
_tempnam,'tempnam',\
_tgamma,'tgamma',\
_tgammaf,'tgammaf',\
_time,'time',\
_tls_alloc,'tls_alloc',\
_tmpfile,'tmpfile',\
_tmpnam,'tmpnam',\
_toascii,'toascii',\
_tolower,'tolower',\
_toupper,'toupper',\
_towctrans,'towctrans',\
_towlower,'towlower',\
_towupper,'towupper',\
_trunc,'trunc',\
_truncf,'truncf',\
_ungetc,'ungetc',\
_user_alloc,'user_alloc',\
_validate_pe,'validate_pe',\
_vasniprintf,'vasniprintf',\
_vasnprintf,'vasnprintf',\
_vdiprintf,'vdiprintf',\
_vdprintf,'vdprintf',\
_vfiprintf,'vfiprintf',\
_vfiscanf,'vfiscanf',\
_vfprintf,'vfprintf',\
_vfscanf,'vfscanf',\
_vscanf,'vscanf',\
_vsnprintf,'vsnprintf',\
_vsprintf,'vsprintf',\
_vsscanf,'vsscanf',\
_wcrtomb,'wcrtomb',\
_wctrans,'wctrans',\
_wctype,'wctype',\
_write,'write',\
_write_file,'write_file',\
_y0,'y0',\
_y0f,'y0f',\
_y1,'y1',\
_y1f,'y1f',\
_yn,'yn',\
_ynf,'ynf'

View File

@@ -0,0 +1,348 @@
import libfreetype,\
FTC_CMapCache_Lookup,'FTC_CMapCache_Lookup',\
FTC_CMapCache_New,'FTC_CMapCache_New',\
FTC_ImageCache_Lookup,'FTC_ImageCache_Lookup',\
FTC_ImageCache_LookupScaler,'FTC_ImageCache_LookupScaler',\
FTC_ImageCache_New,'FTC_ImageCache_New',\
FTC_Manager_Done,'FTC_Manager_Done',\
FTC_Manager_LookupFace,'FTC_Manager_LookupFace',\
FTC_Manager_LookupSize,'FTC_Manager_LookupSize',\
FTC_Manager_New,'FTC_Manager_New',\
FTC_Manager_RemoveFaceID,'FTC_Manager_RemoveFaceID',\
FTC_Manager_Reset,'FTC_Manager_Reset',\
FTC_Node_Unref,'FTC_Node_Unref',\
FTC_SBitCache_Lookup,'FTC_SBitCache_Lookup',\
FTC_SBitCache_LookupScaler,'FTC_SBitCache_LookupScaler',\
FTC_SBitCache_New,'FTC_SBitCache_New',\
FT_Activate_Size,'FT_Activate_Size',\
FT_Add_Default_Modules,'FT_Add_Default_Modules',\
FT_Add_Module,'FT_Add_Module',\
FT_Angle_Diff,'FT_Angle_Diff',\
FT_Atan2,'FT_Atan2',\
FT_Attach_File,'FT_Attach_File',\
FT_Attach_Stream,'FT_Attach_Stream',\
FT_Bitmap_Convert,'FT_Bitmap_Convert',\
FT_Bitmap_Copy,'FT_Bitmap_Copy',\
FT_Bitmap_Done,'FT_Bitmap_Done',\
FT_Bitmap_Embolden,'FT_Bitmap_Embolden',\
FT_Bitmap_New,'FT_Bitmap_New',\
FT_CMap_Done,'FT_CMap_Done',\
FT_CMap_New,'FT_CMap_New',\
FT_CeilFix,'FT_CeilFix',\
FT_ClassicKern_Free,'FT_ClassicKern_Free',\
FT_ClassicKern_Validate,'FT_ClassicKern_Validate',\
FT_Cos,'FT_Cos',\
FT_DivFix,'FT_DivFix',\
FT_Done_Face,'FT_Done_Face',\
FT_Done_FreeType,'FT_Done_FreeType',\
FT_Done_Glyph,'FT_Done_Glyph',\
FT_Done_GlyphSlot,'FT_Done_GlyphSlot',\
FT_Done_Library,'FT_Done_Library',\
FT_Done_Memory,'FT_Done_Memory',\
FT_Done_Size,'FT_Done_Size',\
FT_Face_CheckTrueTypePatents,'FT_Face_CheckTrueTypePatents',\
FT_Face_GetCharVariantIndex,'FT_Face_GetCharVariantIndex',\
FT_Face_GetCharVariantIsDefault,'FT_Face_GetCharVariantIsDefault',\
FT_Face_GetCharsOfVariant,'FT_Face_GetCharsOfVariant',\
FT_Face_GetVariantSelectors,'FT_Face_GetVariantSelectors',\
FT_Face_GetVariantsOfChar,'FT_Face_GetVariantsOfChar',\
FT_Face_SetUnpatentedHinting,'FT_Face_SetUnpatentedHinting',\
FT_FloorFix,'FT_FloorFix',\
FT_Get_Advance,'FT_Get_Advance',\
FT_Get_Advances,'FT_Get_Advances',\
FT_Get_BDF_Charset_ID,'FT_Get_BDF_Charset_ID',\
FT_Get_BDF_Property,'FT_Get_BDF_Property',\
FT_Get_CID_From_Glyph_Index,'FT_Get_CID_From_Glyph_Index',\
FT_Get_CID_Is_Internally_CID_Keyed,'FT_Get_CID_Is_Internally_CID_Keyed',\
FT_Get_CID_Registry_Ordering_Supplement,'FT_Get_CID_Registry_Ordering_Supplement',\
FT_Get_CMap_Format,'FT_Get_CMap_Format',\
FT_Get_CMap_Language_ID,'FT_Get_CMap_Language_ID',\
FT_Get_Char_Index,'FT_Get_Char_Index',\
FT_Get_Charmap_Index,'FT_Get_Charmap_Index',\
FT_Get_FSType_Flags,'FT_Get_FSType_Flags',\
FT_Get_First_Char,'FT_Get_First_Char',\
FT_Get_Gasp,'FT_Get_Gasp',\
FT_Get_Glyph,'FT_Get_Glyph',\
FT_Get_Glyph_Name,'FT_Get_Glyph_Name',\
FT_Get_Kerning,'FT_Get_Kerning',\
FT_Get_MM_Var,'FT_Get_MM_Var',\
FT_Get_Module,'FT_Get_Module',\
FT_Get_Module_Interface,'FT_Get_Module_Interface',\
FT_Get_Multi_Master,'FT_Get_Multi_Master',\
FT_Get_Name_Index,'FT_Get_Name_Index',\
FT_Get_Next_Char,'FT_Get_Next_Char',\
FT_Get_PFR_Advance,'FT_Get_PFR_Advance',\
FT_Get_PFR_Kerning,'FT_Get_PFR_Kerning',\
FT_Get_PFR_Metrics,'FT_Get_PFR_Metrics',\
FT_Get_PS_Font_Info,'FT_Get_PS_Font_Info',\
FT_Get_PS_Font_Private,'FT_Get_PS_Font_Private',\
FT_Get_PS_Font_Value,'FT_Get_PS_Font_Value',\
FT_Get_Postscript_Name,'FT_Get_Postscript_Name',\
FT_Get_Renderer,'FT_Get_Renderer',\
FT_Get_Sfnt_Name,'FT_Get_Sfnt_Name',\
FT_Get_Sfnt_Name_Count,'FT_Get_Sfnt_Name_Count',\
FT_Get_Sfnt_Table,'FT_Get_Sfnt_Table',\
FT_Get_SubGlyph_Info,'FT_Get_SubGlyph_Info',\
FT_Get_Track_Kerning,'FT_Get_Track_Kerning',\
FT_Get_TrueType_Engine_Type,'FT_Get_TrueType_Engine_Type',\
FT_GlyphLoader_Add,'FT_GlyphLoader_Add',\
FT_GlyphLoader_CheckPoints,'FT_GlyphLoader_CheckPoints',\
FT_GlyphLoader_CheckSubGlyphs,'FT_GlyphLoader_CheckSubGlyphs',\
FT_GlyphLoader_CopyPoints,'FT_GlyphLoader_CopyPoints',\
FT_GlyphLoader_CreateExtra,'FT_GlyphLoader_CreateExtra',\
FT_GlyphLoader_Done,'FT_GlyphLoader_Done',\
FT_GlyphLoader_New,'FT_GlyphLoader_New',\
FT_GlyphLoader_Prepare,'FT_GlyphLoader_Prepare',\
FT_GlyphLoader_Reset,'FT_GlyphLoader_Reset',\
FT_GlyphLoader_Rewind,'FT_GlyphLoader_Rewind',\
FT_GlyphSlot_Embolden,'FT_GlyphSlot_Embolden',\
FT_GlyphSlot_Oblique,'FT_GlyphSlot_Oblique',\
FT_GlyphSlot_Own_Bitmap,'FT_GlyphSlot_Own_Bitmap',\
FT_Glyph_Copy,'FT_Glyph_Copy',\
FT_Glyph_Get_CBox,'FT_Glyph_Get_CBox',\
FT_Glyph_Stroke,'FT_Glyph_Stroke',\
FT_Glyph_StrokeBorder,'FT_Glyph_StrokeBorder',\
FT_Glyph_To_Bitmap,'FT_Glyph_To_Bitmap',\
FT_Glyph_Transform,'FT_Glyph_Transform',\
FT_Has_PS_Glyph_Names,'FT_Has_PS_Glyph_Names',\
FT_Hypot,'FT_Hypot',\
FT_Init_FreeType,'FT_Init_FreeType',\
FT_Library_SetLcdFilter,'FT_Library_SetLcdFilter',\
FT_Library_SetLcdFilterWeights,'FT_Library_SetLcdFilterWeights',\
FT_Library_Version,'FT_Library_Version',\
FT_List_Add,'FT_List_Add',\
FT_List_Finalize,'FT_List_Finalize',\
FT_List_Find,'FT_List_Find',\
FT_List_Insert,'FT_List_Insert',\
FT_List_Iterate,'FT_List_Iterate',\
FT_List_Remove,'FT_List_Remove',\
FT_List_Up,'FT_List_Up',\
FT_Load_Char,'FT_Load_Char',\
FT_Load_Glyph,'FT_Load_Glyph',\
FT_Load_Sfnt_Table,'FT_Load_Sfnt_Table',\
FT_Lookup_Renderer,'FT_Lookup_Renderer',\
FT_MSB,'FT_MSB',\
FT_Match_Size,'FT_Match_Size',\
FT_Matrix_Invert,'FT_Matrix_Invert',\
FT_Matrix_Multiply,'FT_Matrix_Multiply',\
FT_Matrix_Multiply_Scaled,'FT_Matrix_Multiply_Scaled',\
FT_MulDiv,'FT_MulDiv',\
FT_MulDiv_No_Round,'FT_MulDiv_No_Round',\
FT_MulFix,'FT_MulFix',\
FT_New_Face,'FT_New_Face',\
FT_New_GlyphSlot,'FT_New_GlyphSlot',\
FT_New_Library,'FT_New_Library',\
FT_New_Memory,'FT_New_Memory',\
FT_New_Memory_Face,'FT_New_Memory_Face',\
FT_New_Size,'FT_New_Size',\
FT_OpenType_Free,'FT_OpenType_Free',\
FT_OpenType_Validate,'FT_OpenType_Validate',\
FT_Open_Face,'FT_Open_Face',\
FT_Outline_Check,'FT_Outline_Check',\
FT_Outline_Copy,'FT_Outline_Copy',\
FT_Outline_Decompose,'FT_Outline_Decompose',\
FT_Outline_Done,'FT_Outline_Done',\
FT_Outline_Done_Internal,'FT_Outline_Done_Internal',\
FT_Outline_Embolden,'FT_Outline_Embolden',\
FT_Outline_EmboldenXY,'FT_Outline_EmboldenXY',\
FT_Outline_GetInsideBorder,'FT_Outline_GetInsideBorder',\
FT_Outline_GetOutsideBorder,'FT_Outline_GetOutsideBorder',\
FT_Outline_Get_BBox,'FT_Outline_Get_BBox',\
FT_Outline_Get_Bitmap,'FT_Outline_Get_Bitmap',\
FT_Outline_Get_CBox,'FT_Outline_Get_CBox',\
FT_Outline_Get_Orientation,'FT_Outline_Get_Orientation',\
FT_Outline_New,'FT_Outline_New',\
FT_Outline_New_Internal,'FT_Outline_New_Internal',\
FT_Outline_Render,'FT_Outline_Render',\
FT_Outline_Reverse,'FT_Outline_Reverse',\
FT_Outline_Transform,'FT_Outline_Transform',\
FT_Outline_Translate,'FT_Outline_Translate',\
FT_Property_Get,'FT_Property_Get',\
FT_Property_Set,'FT_Property_Set',\
FT_Raccess_Get_DataOffsets,'FT_Raccess_Get_DataOffsets',\
FT_Raccess_Get_HeaderInfo,'FT_Raccess_Get_HeaderInfo',\
FT_Raccess_Guess,'FT_Raccess_Guess',\
FT_Reference_Face,'FT_Reference_Face',\
FT_Reference_Library,'FT_Reference_Library',\
FT_Remove_Module,'FT_Remove_Module',\
FT_Render_Glyph,'FT_Render_Glyph',\
FT_Render_Glyph_Internal,'FT_Render_Glyph_Internal',\
FT_Request_Metrics,'FT_Request_Metrics',\
FT_Request_Size,'FT_Request_Size',\
FT_RoundFix,'FT_RoundFix',\
FT_Select_Charmap,'FT_Select_Charmap',\
FT_Select_Metrics,'FT_Select_Metrics',\
FT_Select_Size,'FT_Select_Size',\
FT_Set_Char_Size,'FT_Set_Char_Size',\
FT_Set_Charmap,'FT_Set_Charmap',\
FT_Set_Debug_Hook,'FT_Set_Debug_Hook',\
FT_Set_MM_Blend_Coordinates,'FT_Set_MM_Blend_Coordinates',\
FT_Set_MM_Design_Coordinates,'FT_Set_MM_Design_Coordinates',\
FT_Set_Pixel_Sizes,'FT_Set_Pixel_Sizes',\
FT_Set_Renderer,'FT_Set_Renderer',\
FT_Set_Transform,'FT_Set_Transform',\
FT_Set_Var_Blend_Coordinates,'FT_Set_Var_Blend_Coordinates',\
FT_Set_Var_Design_Coordinates,'FT_Set_Var_Design_Coordinates',\
FT_Sfnt_Table_Info,'FT_Sfnt_Table_Info',\
FT_Sin,'FT_Sin',\
FT_SqrtFixed,'FT_SqrtFixed',\
FT_Stream_Close,'FT_Stream_Close',\
FT_Stream_EnterFrame,'FT_Stream_EnterFrame',\
FT_Stream_ExitFrame,'FT_Stream_ExitFrame',\
FT_Stream_ExtractFrame,'FT_Stream_ExtractFrame',\
FT_Stream_Free,'FT_Stream_Free',\
FT_Stream_GetChar,'FT_Stream_GetChar',\
FT_Stream_GetULong,'FT_Stream_GetULong',\
FT_Stream_GetULongLE,'FT_Stream_GetULongLE',\
FT_Stream_GetUOffset,'FT_Stream_GetUOffset',\
FT_Stream_GetUShort,'FT_Stream_GetUShort',\
FT_Stream_GetUShortLE,'FT_Stream_GetUShortLE',\
FT_Stream_New,'FT_Stream_New',\
FT_Stream_Open,'FT_Stream_Open',\
FT_Stream_OpenBzip2,'FT_Stream_OpenBzip2',\
FT_Stream_OpenGzip,'FT_Stream_OpenGzip',\
FT_Stream_OpenLZW,'FT_Stream_OpenLZW',\
FT_Stream_OpenMemory,'FT_Stream_OpenMemory',\
FT_Stream_Pos,'FT_Stream_Pos',\
FT_Stream_Read,'FT_Stream_Read',\
FT_Stream_ReadAt,'FT_Stream_ReadAt',\
FT_Stream_ReadChar,'FT_Stream_ReadChar',\
FT_Stream_ReadFields,'FT_Stream_ReadFields',\
FT_Stream_ReadULong,'FT_Stream_ReadULong',\
FT_Stream_ReadULongLE,'FT_Stream_ReadULongLE',\
FT_Stream_ReadUOffset,'FT_Stream_ReadUOffset',\
FT_Stream_ReadUShort,'FT_Stream_ReadUShort',\
FT_Stream_ReadUShortLE,'FT_Stream_ReadUShortLE',\
FT_Stream_ReleaseFrame,'FT_Stream_ReleaseFrame',\
FT_Stream_Seek,'FT_Stream_Seek',\
FT_Stream_Skip,'FT_Stream_Skip',\
FT_Stream_TryRead,'FT_Stream_TryRead',\
FT_Stroker_BeginSubPath,'FT_Stroker_BeginSubPath',\
FT_Stroker_ConicTo,'FT_Stroker_ConicTo',\
FT_Stroker_CubicTo,'FT_Stroker_CubicTo',\
FT_Stroker_Done,'FT_Stroker_Done',\
FT_Stroker_EndSubPath,'FT_Stroker_EndSubPath',\
FT_Stroker_Export,'FT_Stroker_Export',\
FT_Stroker_ExportBorder,'FT_Stroker_ExportBorder',\
FT_Stroker_GetBorderCounts,'FT_Stroker_GetBorderCounts',\
FT_Stroker_GetCounts,'FT_Stroker_GetCounts',\
FT_Stroker_LineTo,'FT_Stroker_LineTo',\
FT_Stroker_New,'FT_Stroker_New',\
FT_Stroker_ParseOutline,'FT_Stroker_ParseOutline',\
FT_Stroker_Rewind,'FT_Stroker_Rewind',\
FT_Stroker_Set,'FT_Stroker_Set',\
FT_Tan,'FT_Tan',\
FT_Trace_Get_Count,'FT_Trace_Get_Count',\
FT_Trace_Get_Name,'FT_Trace_Get_Name',\
FT_TrueTypeGX_Free,'FT_TrueTypeGX_Free',\
FT_TrueTypeGX_Validate,'FT_TrueTypeGX_Validate',\
FT_Vector_From_Polar,'FT_Vector_From_Polar',\
FT_Vector_Length,'FT_Vector_Length',\
FT_Vector_Polarize,'FT_Vector_Polarize',\
FT_Vector_Rotate,'FT_Vector_Rotate',\
FT_Vector_Transform,'FT_Vector_Transform',\
FT_Vector_Transform_Scaled,'FT_Vector_Transform_Scaled',\
FT_Vector_Unit,'FT_Vector_Unit',\
TT_New_Context,'TT_New_Context',\
TT_RunIns,'TT_RunIns',\
af_autofitter_interface,'af_autofitter_interface',\
af_cjk_script_class,'af_cjk_script_class',\
af_dummy_script_class,'af_dummy_script_class',\
af_glyph_hints_dump_edges,'af_glyph_hints_dump_edges',\
af_glyph_hints_dump_points,'af_glyph_hints_dump_points',\
af_glyph_hints_dump_segments,'af_glyph_hints_dump_segments',\
af_glyph_hints_get_num_segments,'af_glyph_hints_get_num_segments',\
af_glyph_hints_get_segment_offset,'af_glyph_hints_get_segment_offset',\
af_indic_script_class,'af_indic_script_class',\
af_latin_script_class,'af_latin_script_class',\
af_property_get,'af_property_get',\
af_property_get_face_globals,'af_property_get_face_globals',\
af_property_set,'af_property_set',\
afm_parser_funcs,'afm_parser_funcs',\
autofit_module_class,'autofit_module_class',\
bdf_cmap_class,'bdf_cmap_class',\
bdf_driver_class,'bdf_driver_class',\
cff_cmap_encoding_class_rec,'cff_cmap_encoding_class_rec',\
cff_cmap_unicode_class_rec,'cff_cmap_unicode_class_rec',\
cff_driver_class,'cff_driver_class',\
ft_bitmap_glyph_class,'ft_bitmap_glyph_class',\
ft_corner_is_flat,'ft_corner_is_flat',\
ft_corner_orientation,'ft_corner_orientation',\
ft_debug_init,'ft_debug_init',\
ft_glyphslot_alloc_bitmap,'ft_glyphslot_alloc_bitmap',\
ft_glyphslot_free_bitmap,'ft_glyphslot_free_bitmap',\
ft_glyphslot_set_bitmap,'ft_glyphslot_set_bitmap',\
ft_gray_for_premultiplied_srgb_bgra,'ft_gray_for_premultiplied_srgb_bgra',\
ft_grays_raster,'ft_grays_raster',\
ft_highpow2,'ft_highpow2',\
ft_lzwstate_done,'ft_lzwstate_done',\
ft_lzwstate_init,'ft_lzwstate_init',\
ft_lzwstate_io,'ft_lzwstate_io',\
ft_lzwstate_reset,'ft_lzwstate_reset',\
ft_mem_alloc,'ft_mem_alloc',\
ft_mem_dup,'ft_mem_dup',\
ft_mem_free,'ft_mem_free',\
ft_mem_qalloc,'ft_mem_qalloc',\
ft_mem_qrealloc,'ft_mem_qrealloc',\
ft_mem_realloc,'ft_mem_realloc',\
ft_mem_strcpyn,'ft_mem_strcpyn',\
ft_mem_strdup,'ft_mem_strdup',\
ft_module_get_service,'ft_module_get_service',\
ft_outline_glyph_class,'ft_outline_glyph_class',\
ft_property_do,'ft_property_do',\
ft_raccess_guess_table,'ft_raccess_guess_table',\
ft_raster1_renderer_class,'ft_raster1_renderer_class',\
ft_raster5_renderer_class,'ft_raster5_renderer_class',\
ft_service_list_lookup,'ft_service_list_lookup',\
ft_smooth_lcd_renderer_class,'ft_smooth_lcd_renderer_class',\
ft_smooth_lcdv_renderer_class,'ft_smooth_lcdv_renderer_class',\
ft_smooth_renderer_class,'ft_smooth_renderer_class',\
ft_standard_raster,'ft_standard_raster',\
ft_synthesize_vertical_metrics,'ft_synthesize_vertical_metrics',\
ft_validator_error,'ft_validator_error',\
ft_validator_init,'ft_validator_init',\
ft_validator_run,'ft_validator_run',\
ftc_basic_image_cache_class,'ftc_basic_image_cache_class',\
ftc_basic_image_family_class,'ftc_basic_image_family_class',\
ftc_basic_sbit_cache_class,'ftc_basic_sbit_cache_class',\
ftc_basic_sbit_family_class,'ftc_basic_sbit_family_class',\
ftc_cmap_cache_class,'ftc_cmap_cache_class',\
ftc_face_list_class,'ftc_face_list_class',\
ftc_size_list_class,'ftc_size_list_class',\
longjmp,'longjmp',\
otv_module_class,'otv_module_class',\
pcf_cmap_class,'pcf_cmap_class',\
pcf_driver_class,'pcf_driver_class',\
pfr_cmap_class_rec,'pfr_cmap_class_rec',\
pfr_driver_class,'pfr_driver_class',\
pfr_metrics_service_rec,'pfr_metrics_service_rec',\
ps_hints_apply,'ps_hints_apply',\
ps_parser_funcs,'ps_parser_funcs',\
ps_table_funcs,'ps_table_funcs',\
psaux_module_class,'psaux_module_class',\
pshinter_module_class,'pshinter_module_class',\
psnames_module_class,'psnames_module_class',\
setjmp,'setjmp',\
sfnt_module_class,'sfnt_module_class',\
t1_builder_funcs,'t1_builder_funcs',\
t1_cmap_classes,'t1_cmap_classes',\
t1_cmap_custom_class_rec,'t1_cmap_custom_class_rec',\
t1_cmap_expert_class_rec,'t1_cmap_expert_class_rec',\
t1_cmap_standard_class_rec,'t1_cmap_standard_class_rec',\
t1_cmap_unicode_class_rec,'t1_cmap_unicode_class_rec',\
t1_decoder_funcs,'t1_decoder_funcs',\
t1_driver_class,'t1_driver_class',\
t1cid_driver_class,'t1cid_driver_class',\
t42_driver_class,'t42_driver_class',\
tt_cmap0_class_rec,'tt_cmap0_class_rec',\
tt_cmap10_class_rec,'tt_cmap10_class_rec',\
tt_cmap12_class_rec,'tt_cmap12_class_rec',\
tt_cmap13_class_rec,'tt_cmap13_class_rec',\
tt_cmap14_class_rec,'tt_cmap14_class_rec',\
tt_cmap2_class_rec,'tt_cmap2_class_rec',\
tt_cmap4_class_rec,'tt_cmap4_class_rec',\
tt_cmap6_class_rec,'tt_cmap6_class_rec',\
tt_cmap8_class_rec,'tt_cmap8_class_rec',\
tt_default_graphics_state,'tt_default_graphics_state',\
tt_driver_class,'tt_driver_class',\
winfnt_driver_class,'winfnt_driver_class'

View File

@@ -0,0 +1,113 @@
EXPORTS,'EXPORTS',\
mpg123_add_string,'mpg123_add_string',\
mpg123_add_substring,'mpg123_add_substring',\
mpg123_chomp_string,'mpg123_chomp_string',\
mpg123_clip,'mpg123_clip',\
mpg123_close,'mpg123_close',\
mpg123_copy_string,'mpg123_copy_string',\
mpg123_current_decoder,'mpg123_current_decoder',\
mpg123_decode,'mpg123_decode',\
mpg123_decode_frame,'mpg123_decode_frame',\
mpg123_decode_frame_32,'mpg123_decode_frame_32',\
mpg123_decoder,'mpg123_decoder',\
mpg123_decoders,'mpg123_decoders',\
mpg123_delete,'mpg123_delete',\
mpg123_delete_pars,'mpg123_delete_pars',\
mpg123_enc_from_id3,'mpg123_enc_from_id3',\
mpg123_encodings,'mpg123_encodings',\
mpg123_encsize,'mpg123_encsize',\
mpg123_eq,'mpg123_eq',\
mpg123_errcode,'mpg123_errcode',\
mpg123_exit,'mpg123_exit',\
mpg123_feature,'mpg123_feature',\
mpg123_feed,'mpg123_feed',\
mpg123_feedseek,'mpg123_feedseek',\
mpg123_feedseek_32,'mpg123_feedseek_32',\
mpg123_fmt,'mpg123_fmt',\
mpg123_fmt_all,'mpg123_fmt_all',\
mpg123_fmt_none,'mpg123_fmt_none',\
mpg123_fmt_support,'mpg123_fmt_support',\
mpg123_format,'mpg123_format',\
mpg123_format_all,'mpg123_format_all',\
mpg123_format_none,'mpg123_format_none',\
mpg123_format_support,'mpg123_format_support',\
mpg123_framebyframe_decode,'mpg123_framebyframe_decode',\
mpg123_framebyframe_decode_32,'mpg123_framebyframe_decode_32',\
mpg123_framebyframe_next,'mpg123_framebyframe_next',\
mpg123_framedata,'mpg123_framedata',\
mpg123_framepos,'mpg123_framepos',\
mpg123_framepos_32,'mpg123_framepos_32',\
mpg123_free_string,'mpg123_free_string',\
mpg123_geteq,'mpg123_geteq',\
mpg123_getformat,'mpg123_getformat',\
mpg123_getpar,'mpg123_getpar',\
mpg123_getparam,'mpg123_getparam',\
mpg123_getstate,'mpg123_getstate',\
mpg123_getvolume,'mpg123_getvolume',\
mpg123_grow_string,'mpg123_grow_string',\
mpg123_icy,'mpg123_icy',\
mpg123_icy2utf8,'mpg123_icy2utf8',\
mpg123_id3,'mpg123_id3',\
mpg123_index,'mpg123_index',\
mpg123_index_32,'mpg123_index_32',\
mpg123_info,'mpg123_info',\
mpg123_init,'mpg123_init',\
mpg123_init_string,'mpg123_init_string',\
mpg123_length,'mpg123_length',\
mpg123_length_32,'mpg123_length_32',\
mpg123_meta_check,'mpg123_meta_check',\
mpg123_meta_free,'mpg123_meta_free',\
mpg123_new,'mpg123_new',\
mpg123_new_pars,'mpg123_new_pars',\
mpg123_noise,'mpg123_noise',\
mpg123_open,'mpg123_open',\
mpg123_open_32,'mpg123_open_32',\
mpg123_open_fd,'mpg123_open_fd',\
mpg123_open_fd_32,'mpg123_open_fd_32',\
mpg123_open_feed,'mpg123_open_feed',\
mpg123_open_handle,'mpg123_open_handle',\
mpg123_open_handle_32,'mpg123_open_handle_32',\
mpg123_outblock,'mpg123_outblock',\
mpg123_par,'mpg123_par',\
mpg123_param,'mpg123_param',\
mpg123_parnew,'mpg123_parnew',\
mpg123_plain_strerror,'mpg123_plain_strerror',\
mpg123_position,'mpg123_position',\
mpg123_position_32,'mpg123_position_32',\
mpg123_rates,'mpg123_rates',\
mpg123_read,'mpg123_read',\
mpg123_replace_buffer,'mpg123_replace_buffer',\
mpg123_replace_reader,'mpg123_replace_reader',\
mpg123_replace_reader_32,'mpg123_replace_reader_32',\
mpg123_replace_reader_handle,'mpg123_replace_reader_handle',\
mpg123_replace_reader_handle_32,'mpg123_replace_reader_handle_32',\
mpg123_reset_eq,'mpg123_reset_eq',\
mpg123_resize_string,'mpg123_resize_string',\
mpg123_safe_buffer,'mpg123_safe_buffer',\
mpg123_scan,'mpg123_scan',\
mpg123_seek,'mpg123_seek',\
mpg123_seek_32,'mpg123_seek_32',\
mpg123_seek_frame,'mpg123_seek_frame',\
mpg123_seek_frame_32,'mpg123_seek_frame_32',\
mpg123_set_filesize,'mpg123_set_filesize',\
mpg123_set_filesize_32,'mpg123_set_filesize_32',\
mpg123_set_index,'mpg123_set_index',\
mpg123_set_index_32,'mpg123_set_index_32',\
mpg123_set_string,'mpg123_set_string',\
mpg123_set_substring,'mpg123_set_substring',\
mpg123_spf,'mpg123_spf',\
mpg123_store_utf8,'mpg123_store_utf8',\
mpg123_strerror,'mpg123_strerror',\
mpg123_strlen,'mpg123_strlen',\
mpg123_supported_decoders,'mpg123_supported_decoders',\
mpg123_tell,'mpg123_tell',\
mpg123_tell_32,'mpg123_tell_32',\
mpg123_tell_stream,'mpg123_tell_stream',\
mpg123_tell_stream_32,'mpg123_tell_stream_32',\
mpg123_tellframe,'mpg123_tellframe',\
mpg123_tellframe_32,'mpg123_tellframe_32',\
mpg123_timeframe,'mpg123_timeframe',\
mpg123_timeframe_32,'mpg123_timeframe_32',\
mpg123_tpf,'mpg123_tpf',\
mpg123_volume,'mpg123_volume',\
mpg123_volume_change,'mpg123_volume_change',\

View File

@@ -0,0 +1,243 @@
EXPORTS,'EXPORTS',\
import libpng16,\
png_access_version_number,'png_access_version_number',\
png_set_sig_bytes,'png_set_sig_bytes',\
png_sig_cmp,'png_sig_cmp',\
png_create_read_struct,'png_create_read_struct',\
png_create_write_struct,'png_create_write_struct',\
png_get_compression_buffer_size,'png_get_compression_buffer_size',\
png_set_compression_buffer_size,'png_set_compression_buffer_size',\
png_set_longjmp_fn,'png_set_longjmp_fn',\
png_longjmp,'png_longjmp',\
png_reset_zstream,'png_reset_zstream',\
png_create_read_struct_2,'png_create_read_struct_2',\
png_create_write_struct_2,'png_create_write_struct_2',\
png_write_sig,'png_write_sig',\
png_write_chunk,'png_write_chunk',\
png_write_chunk_start,'png_write_chunk_start',\
png_write_chunk_data,'png_write_chunk_data',\
png_write_chunk_end,'png_write_chunk_end',\
png_create_info_struct,'png_create_info_struct',\
png_info_init_3,'png_info_init_3',\
png_write_info_before_PLTE,'png_write_info_before_PLTE',\
png_write_info,'png_write_info',\
png_read_info,'png_read_info',\
png_convert_to_rfc1123,'png_convert_to_rfc1123',\
png_convert_to_rfc1123_buffer,'png_convert_to_rfc1123_buffer',\
png_convert_from_struct_tm,'png_convert_from_struct_tm',\
png_convert_from_time_t,'png_convert_from_time_t',\
png_set_expand,'png_set_expand',\
png_set_expand_gray_1_2_4_to_8,'png_set_expand_gray_1_2_4_to_8',\
png_set_palette_to_rgb,'png_set_palette_to_rgb',\
png_set_tRNS_to_alpha,'png_set_tRNS_to_alpha',\
png_set_expand_16,'png_set_expand_16',\
png_set_bgr,'png_set_bgr',\
png_set_gray_to_rgb,'png_set_gray_to_rgb',\
png_set_rgb_to_gray,'png_set_rgb_to_gray',\
png_set_rgb_to_gray_fixed,'png_set_rgb_to_gray_fixed',\
png_get_rgb_to_gray_status,'png_get_rgb_to_gray_status',\
png_build_grayscale_palette,'png_build_grayscale_palette',\
png_set_alpha_mode,'png_set_alpha_mode',\
png_set_alpha_mode_fixed,'png_set_alpha_mode_fixed',\
png_set_strip_alpha,'png_set_strip_alpha',\
png_set_swap_alpha,'png_set_swap_alpha',\
png_set_invert_alpha,'png_set_invert_alpha',\
png_set_filler,'png_set_filler',\
png_set_add_alpha,'png_set_add_alpha',\
png_set_swap,'png_set_swap',\
png_set_packing,'png_set_packing',\
png_set_packswap,'png_set_packswap',\
png_set_shift,'png_set_shift',\
png_set_interlace_handling,'png_set_interlace_handling',\
png_set_invert_mono,'png_set_invert_mono',\
png_set_background,'png_set_background',\
png_set_background_fixed,'png_set_background_fixed',\
png_set_scale_16,'png_set_scale_16',\
png_set_strip_16,'png_set_strip_16',\
png_set_quantize,'png_set_quantize',\
png_set_gamma,'png_set_gamma',\
png_set_gamma_fixed,'png_set_gamma_fixed',\
png_set_flush,'png_set_flush',\
png_write_flush,'png_write_flush',\
png_start_read_image,'png_start_read_image',\
png_read_update_info,'png_read_update_info',\
png_read_rows,'png_read_rows',\
png_read_row,'png_read_row',\
png_read_image,'png_read_image',\
png_write_row,'png_write_row',\
png_write_rows,'png_write_rows',\
png_write_image,'png_write_image',\
png_write_end,'png_write_end',\
png_read_end,'png_read_end',\
png_destroy_info_struct,'png_destroy_info_struct',\
png_destroy_read_struct,'png_destroy_read_struct',\
png_destroy_write_struct,'png_destroy_write_struct',\
png_set_crc_action,'png_set_crc_action',\
png_set_filter,'png_set_filter',\
png_set_filter_heuristics,'png_set_filter_heuristics',\
png_set_filter_heuristics_fixed,'png_set_filter_heuristics_fixed',\
png_set_compression_level,'png_set_compression_level',\
png_set_compression_mem_level,'png_set_compression_mem_level',\
png_set_compression_strategy,'png_set_compression_strategy',\
png_set_compression_window_bits,'png_set_compression_window_bits',\
png_set_compression_method,'png_set_compression_method',\
png_set_text_compression_level,'png_set_text_compression_level',\
png_set_text_compression_mem_level,'png_set_text_compression_mem_level',\
png_set_text_compression_strategy,'png_set_text_compression_strategy',\
png_set_text_compression_window_bits,'png_set_text_compression_window_bits',\
png_set_text_compression_method,'png_set_text_compression_method',\
png_init_io,'png_init_io',\
png_set_error_fn,'png_set_error_fn',\
png_get_error_ptr,'png_get_error_ptr',\
png_set_write_fn,'png_set_write_fn',\
png_set_read_fn,'png_set_read_fn',\
png_get_io_ptr,'png_get_io_ptr',\
png_set_read_status_fn,'png_set_read_status_fn',\
png_set_write_status_fn,'png_set_write_status_fn',\
png_set_mem_fn,'png_set_mem_fn',\
png_get_mem_ptr,'png_get_mem_ptr',\
png_set_read_user_transform_fn,'png_set_read_user_transform_fn',\
png_set_write_user_transform_fn,'png_set_write_user_transform_fn',\
png_set_user_transform_info,'png_set_user_transform_info',\
png_get_user_transform_ptr,'png_get_user_transform_ptr',\
png_get_current_row_number,'png_get_current_row_number',\
png_get_current_pass_number,'png_get_current_pass_number',\
png_set_read_user_chunk_fn,'png_set_read_user_chunk_fn',\
png_get_user_chunk_ptr,'png_get_user_chunk_ptr',\
png_set_progressive_read_fn,'png_set_progressive_read_fn',\
png_get_progressive_ptr,'png_get_progressive_ptr',\
png_process_data,'png_process_data',\
png_process_data_pause,'png_process_data_pause',\
png_process_data_skip,'png_process_data_skip',\
png_progressive_combine_row,'png_progressive_combine_row',\
png_malloc,'png_malloc',\
png_calloc,'png_calloc',\
png_malloc_warn,'png_malloc_warn',\
png_free,'png_free',\
png_free_data,'png_free_data',\
png_data_freer,'png_data_freer',\
png_malloc_default,'png_malloc_default',\
png_free_default,'png_free_default',\
png_error,'png_error',\
png_chunk_error,'png_chunk_error',\
png_warning,'png_warning',\
png_chunk_warning,'png_chunk_warning',\
png_benign_error,'png_benign_error',\
png_chunk_benign_error,'png_chunk_benign_error',\
png_set_benign_errors,'png_set_benign_errors',\
png_get_valid,'png_get_valid',\
png_get_rowbytes,'png_get_rowbytes',\
png_get_rows,'png_get_rows',\
png_set_rows,'png_set_rows',\
png_get_channels,'png_get_channels',\
png_get_image_width,'png_get_image_width',\
png_get_image_height,'png_get_image_height',\
png_get_bit_depth,'png_get_bit_depth',\
png_get_color_type,'png_get_color_type',\
png_get_filter_type,'png_get_filter_type',\
png_get_interlace_type,'png_get_interlace_type',\
png_get_compression_type,'png_get_compression_type',\
png_get_pixels_per_meter,'png_get_pixels_per_meter',\
png_get_x_pixels_per_meter,'png_get_x_pixels_per_meter',\
png_get_y_pixels_per_meter,'png_get_y_pixels_per_meter',\
png_get_pixel_aspect_ratio,'png_get_pixel_aspect_ratio',\
png_get_pixel_aspect_ratio_fixed,'png_get_pixel_aspect_ratio_fixed',\
png_get_x_offset_pixels,'png_get_x_offset_pixels',\
png_get_y_offset_pixels,'png_get_y_offset_pixels',\
png_get_x_offset_microns,'png_get_x_offset_microns',\
png_get_y_offset_microns,'png_get_y_offset_microns',\
png_get_signature,'png_get_signature',\
png_get_bKGD,'png_get_bKGD',\
png_set_bKGD,'png_set_bKGD',\
png_get_cHRM,'png_get_cHRM',\
png_get_cHRM_XYZ,'png_get_cHRM_XYZ',\
png_get_cHRM_fixed,'png_get_cHRM_fixed',\
png_get_cHRM_XYZ_fixed,'png_get_cHRM_XYZ_fixed',\
png_set_cHRM,'png_set_cHRM',\
png_set_cHRM_XYZ,'png_set_cHRM_XYZ',\
png_set_cHRM_fixed,'png_set_cHRM_fixed',\
png_set_cHRM_XYZ_fixed,'png_set_cHRM_XYZ_fixed',\
png_get_gAMA,'png_get_gAMA',\
png_get_gAMA_fixed,'png_get_gAMA_fixed',\
png_set_gAMA,'png_set_gAMA',\
png_set_gAMA_fixed,'png_set_gAMA_fixed',\
png_get_hIST,'png_get_hIST',\
png_set_hIST,'png_set_hIST',\
png_get_IHDR,'png_get_IHDR',\
png_set_IHDR,'png_set_IHDR',\
png_get_oFFs,'png_get_oFFs',\
png_set_oFFs,'png_set_oFFs',\
png_get_pCAL,'png_get_pCAL',\
png_set_pCAL,'png_set_pCAL',\
png_get_pHYs,'png_get_pHYs',\
png_set_pHYs,'png_set_pHYs',\
png_get_PLTE,'png_get_PLTE',\
png_set_PLTE,'png_set_PLTE',\
png_get_sBIT,'png_get_sBIT',\
png_set_sBIT,'png_set_sBIT',\
png_get_sRGB,'png_get_sRGB',\
png_set_sRGB,'png_set_sRGB',\
png_set_sRGB_gAMA_and_cHRM,'png_set_sRGB_gAMA_and_cHRM',\
png_get_iCCP,'png_get_iCCP',\
png_set_iCCP,'png_set_iCCP',\
png_get_sPLT,'png_get_sPLT',\
png_set_sPLT,'png_set_sPLT',\
png_get_text,'png_get_text',\
png_set_text,'png_set_text',\
png_get_tIME,'png_get_tIME',\
png_set_tIME,'png_set_tIME',\
png_get_tRNS,'png_get_tRNS',\
png_set_tRNS,'png_set_tRNS',\
png_get_sCAL,'png_get_sCAL',\
png_get_sCAL_fixed,'png_get_sCAL_fixed',\
png_get_sCAL_s,'png_get_sCAL_s',\
png_set_sCAL,'png_set_sCAL',\
png_set_sCAL_fixed,'png_set_sCAL_fixed',\
png_set_sCAL_s,'png_set_sCAL_s',\
png_set_keep_unknown_chunks,'png_set_keep_unknown_chunks',\
png_handle_as_unknown,'png_handle_as_unknown',\
png_set_unknown_chunks,'png_set_unknown_chunks',\
png_set_unknown_chunk_location,'png_set_unknown_chunk_location',\
png_get_unknown_chunks,'png_get_unknown_chunks',\
png_set_invalid,'png_set_invalid',\
png_read_png,'png_read_png',\
png_write_png,'png_write_png',\
png_get_copyright,'png_get_copyright',\
png_get_header_ver,'png_get_header_ver',\
png_get_header_version,'png_get_header_version',\
png_get_libpng_ver,'png_get_libpng_ver',\
png_permit_mng_features,'png_permit_mng_features',\
png_set_user_limits,'png_set_user_limits',\
png_get_user_width_max,'png_get_user_width_max',\
png_get_user_height_max,'png_get_user_height_max',\
png_set_chunk_cache_max,'png_set_chunk_cache_max',\
png_get_chunk_cache_max,'png_get_chunk_cache_max',\
png_set_chunk_malloc_max,'png_set_chunk_malloc_max',\
png_get_chunk_malloc_max,'png_get_chunk_malloc_max',\
png_get_pixels_per_inch,'png_get_pixels_per_inch',\
png_get_x_pixels_per_inch,'png_get_x_pixels_per_inch',\
png_get_y_pixels_per_inch,'png_get_y_pixels_per_inch',\
png_get_x_offset_inches,'png_get_x_offset_inches',\
png_get_x_offset_inches_fixed,'png_get_x_offset_inches_fixed',\
png_get_y_offset_inches,'png_get_y_offset_inches',\
png_get_y_offset_inches_fixed,'png_get_y_offset_inches_fixed',\
png_get_pHYs_dpi,'png_get_pHYs_dpi',\
png_get_io_state,'png_get_io_state',\
png_get_io_chunk_type,'png_get_io_chunk_type',\
png_get_uint_32,'png_get_uint_32',\
png_get_uint_16,'png_get_uint_16',\
png_get_int_32,'png_get_int_32',\
png_get_uint_31,'png_get_uint_31',\
png_save_uint_32,'png_save_uint_32',\
png_save_int_32,'png_save_int_32',\
png_save_uint_16,'png_save_uint_16',\
png_image_begin_read_from_file,'png_image_begin_read_from_file',\
png_image_begin_read_from_stdio,'png_image_begin_read_from_stdio',\
png_image_begin_read_from_memory,'png_image_begin_read_from_memory',\
png_image_finish_read,'png_image_finish_read',\
png_image_free,'png_image_free',\
png_image_write_to_file,'png_image_write_to_file',\
png_image_write_to_stdio,'png_image_write_to_stdio',\
png_set_check_for_invalid_index,'png_set_check_for_invalid_index',\
png_get_palette_max,'png_get_palette_max',\
png_set_option,'png_set_option'

View File

@@ -0,0 +1,148 @@
import pixman-1,\
_pixman_internal_only_get_implementation,'_pixman_internal_only_get_implementation',\
pixman_add_trapezoids,'pixman_add_trapezoids',\
pixman_add_traps,'pixman_add_traps',\
pixman_add_triangles,'pixman_add_triangles',\
pixman_blt,'pixman_blt',\
pixman_composite_glyphs,'pixman_composite_glyphs',\
pixman_composite_glyphs_no_mask,'pixman_composite_glyphs_no_mask',\
pixman_composite_trapezoids,'pixman_composite_trapezoids',\
pixman_composite_triangles,'pixman_composite_triangles',\
pixman_compute_composite_region,'pixman_compute_composite_region',\
pixman_disable_out_of_bounds_workaround,'pixman_disable_out_of_bounds_workaround',\
pixman_edge_init,'pixman_edge_init',\
pixman_edge_step,'pixman_edge_step',\
pixman_f_transform_bounds,'pixman_f_transform_bounds',\
pixman_f_transform_from_pixman_transform,'pixman_f_transform_from_pixman_transform',\
pixman_f_transform_init_identity,'pixman_f_transform_init_identity',\
pixman_f_transform_init_rotate,'pixman_f_transform_init_rotate',\
pixman_f_transform_init_scale,'pixman_f_transform_init_scale',\
pixman_f_transform_init_translate,'pixman_f_transform_init_translate',\
pixman_f_transform_invert,'pixman_f_transform_invert',\
pixman_f_transform_multiply,'pixman_f_transform_multiply',\
pixman_f_transform_point,'pixman_f_transform_point',\
pixman_f_transform_point_3d,'pixman_f_transform_point_3d',\
pixman_f_transform_rotate,'pixman_f_transform_rotate',\
pixman_f_transform_scale,'pixman_f_transform_scale',\
pixman_f_transform_translate,'pixman_f_transform_translate',\
pixman_fill,'pixman_fill',\
pixman_filter_create_separable_convolution,'pixman_filter_create_separable_convolution',\
pixman_format_supported_destination,'pixman_format_supported_destination',\
pixman_format_supported_source,'pixman_format_supported_source',\
pixman_glyph_cache_create,'pixman_glyph_cache_create',\
pixman_glyph_cache_destroy,'pixman_glyph_cache_destroy',\
pixman_glyph_cache_freeze,'pixman_glyph_cache_freeze',\
pixman_glyph_cache_insert,'pixman_glyph_cache_insert',\
pixman_glyph_cache_lookup,'pixman_glyph_cache_lookup',\
pixman_glyph_cache_remove,'pixman_glyph_cache_remove',\
pixman_glyph_cache_thaw,'pixman_glyph_cache_thaw',\
pixman_glyph_get_extents,'pixman_glyph_get_extents',\
pixman_glyph_get_mask_format,'pixman_glyph_get_mask_format',\
pixman_image_composite,'pixman_image_composite',\
pixman_image_composite32,'pixman_image_composite32',\
pixman_image_create_bits,'pixman_image_create_bits',\
pixman_image_create_bits_no_clear,'pixman_image_create_bits_no_clear',\
pixman_image_create_conical_gradient,'pixman_image_create_conical_gradient',\
pixman_image_create_linear_gradient,'pixman_image_create_linear_gradient',\
pixman_image_create_radial_gradient,'pixman_image_create_radial_gradient',\
pixman_image_create_solid_fill,'pixman_image_create_solid_fill',\
pixman_image_fill_boxes,'pixman_image_fill_boxes',\
pixman_image_fill_rectangles,'pixman_image_fill_rectangles',\
pixman_image_get_component_alpha,'pixman_image_get_component_alpha',\
pixman_image_get_data,'pixman_image_get_data',\
pixman_image_get_depth,'pixman_image_get_depth',\
pixman_image_get_destroy_data,'pixman_image_get_destroy_data',\
pixman_image_get_format,'pixman_image_get_format',\
pixman_image_get_height,'pixman_image_get_height',\
pixman_image_get_stride,'pixman_image_get_stride',\
pixman_image_get_width,'pixman_image_get_width',\
pixman_image_ref,'pixman_image_ref',\
pixman_image_set_accessors,'pixman_image_set_accessors',\
pixman_image_set_alpha_map,'pixman_image_set_alpha_map',\
pixman_image_set_clip_region,'pixman_image_set_clip_region',\
pixman_image_set_clip_region32,'pixman_image_set_clip_region32',\
pixman_image_set_component_alpha,'pixman_image_set_component_alpha',\
pixman_image_set_destroy_function,'pixman_image_set_destroy_function',\
pixman_image_set_filter,'pixman_image_set_filter',\
pixman_image_set_has_client_clip,'pixman_image_set_has_client_clip',\
pixman_image_set_indexed,'pixman_image_set_indexed',\
pixman_image_set_repeat,'pixman_image_set_repeat',\
pixman_image_set_source_clipping,'pixman_image_set_source_clipping',\
pixman_image_set_transform,'pixman_image_set_transform',\
pixman_image_unref,'pixman_image_unref',\
pixman_line_fixed_edge_init,'pixman_line_fixed_edge_init',\
pixman_rasterize_edges,'pixman_rasterize_edges',\
pixman_rasterize_trapezoid,'pixman_rasterize_trapezoid',\
pixman_region32_clear,'pixman_region32_clear',\
pixman_region32_contains_point,'pixman_region32_contains_point',\
pixman_region32_contains_rectangle,'pixman_region32_contains_rectangle',\
pixman_region32_copy,'pixman_region32_copy',\
pixman_region32_equal,'pixman_region32_equal',\
pixman_region32_extents,'pixman_region32_extents',\
pixman_region32_fini,'pixman_region32_fini',\
pixman_region32_init,'pixman_region32_init',\
pixman_region32_init_from_image,'pixman_region32_init_from_image',\
pixman_region32_init_rect,'pixman_region32_init_rect',\
pixman_region32_init_rects,'pixman_region32_init_rects',\
pixman_region32_init_with_extents,'pixman_region32_init_with_extents',\
pixman_region32_intersect,'pixman_region32_intersect',\
pixman_region32_intersect_rect,'pixman_region32_intersect_rect',\
pixman_region32_inverse,'pixman_region32_inverse',\
pixman_region32_n_rects,'pixman_region32_n_rects',\
pixman_region32_not_empty,'pixman_region32_not_empty',\
pixman_region32_rectangles,'pixman_region32_rectangles',\
pixman_region32_reset,'pixman_region32_reset',\
pixman_region32_selfcheck,'pixman_region32_selfcheck',\
pixman_region32_subtract,'pixman_region32_subtract',\
pixman_region32_translate,'pixman_region32_translate',\
pixman_region32_union,'pixman_region32_union',\
pixman_region32_union_rect,'pixman_region32_union_rect',\
pixman_region_clear,'pixman_region_clear',\
pixman_region_contains_point,'pixman_region_contains_point',\
pixman_region_contains_rectangle,'pixman_region_contains_rectangle',\
pixman_region_copy,'pixman_region_copy',\
pixman_region_equal,'pixman_region_equal',\
pixman_region_extents,'pixman_region_extents',\
pixman_region_fini,'pixman_region_fini',\
pixman_region_init,'pixman_region_init',\
pixman_region_init_from_image,'pixman_region_init_from_image',\
pixman_region_init_rect,'pixman_region_init_rect',\
pixman_region_init_rects,'pixman_region_init_rects',\
pixman_region_init_with_extents,'pixman_region_init_with_extents',\
pixman_region_intersect,'pixman_region_intersect',\
pixman_region_intersect_rect,'pixman_region_intersect_rect',\
pixman_region_inverse,'pixman_region_inverse',\
pixman_region_n_rects,'pixman_region_n_rects',\
pixman_region_not_empty,'pixman_region_not_empty',\
pixman_region_rectangles,'pixman_region_rectangles',\
pixman_region_reset,'pixman_region_reset',\
pixman_region_selfcheck,'pixman_region_selfcheck',\
pixman_region_set_static_pointers,'pixman_region_set_static_pointers',\
pixman_region_subtract,'pixman_region_subtract',\
pixman_region_translate,'pixman_region_translate',\
pixman_region_union,'pixman_region_union',\
pixman_region_union_rect,'pixman_region_union_rect',\
pixman_sample_ceil_y,'pixman_sample_ceil_y',\
pixman_sample_floor_y,'pixman_sample_floor_y',\
pixman_transform_bounds,'pixman_transform_bounds',\
pixman_transform_from_pixman_f_transform,'pixman_transform_from_pixman_f_transform',\
pixman_transform_init_identity,'pixman_transform_init_identity',\
pixman_transform_init_rotate,'pixman_transform_init_rotate',\
pixman_transform_init_scale,'pixman_transform_init_scale',\
pixman_transform_init_translate,'pixman_transform_init_translate',\
pixman_transform_invert,'pixman_transform_invert',\
pixman_transform_is_identity,'pixman_transform_is_identity',\
pixman_transform_is_int_translate,'pixman_transform_is_int_translate',\
pixman_transform_is_inverse,'pixman_transform_is_inverse',\
pixman_transform_is_scale,'pixman_transform_is_scale',\
pixman_transform_multiply,'pixman_transform_multiply',\
pixman_transform_point,'pixman_transform_point',\
pixman_transform_point_31_16,'pixman_transform_point_31_16',\
pixman_transform_point_31_16_3d,'pixman_transform_point_31_16_3d',\
pixman_transform_point_31_16_affine,'pixman_transform_point_31_16_affine',\
pixman_transform_point_3d,'pixman_transform_point_3d',\
pixman_transform_rotate,'pixman_transform_rotate',\
pixman_transform_scale,'pixman_transform_scale',\
pixman_transform_translate,'pixman_transform_translate',\
pixman_version,'pixman_version',\
pixman_version_string,'pixman_version_string'

View File

@@ -0,0 +1,301 @@
; Macroinstructions for defining and calling procedures
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ local loc
loc = (localbytes+3) and (not 3)
parmbase@proc equ ebp+8
localbase@proc equ ebp-loc
if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,loc
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
close@proc equ
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
virtual at parmbase@proc
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $-(parmbase@proc)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
macro locals
\{ virtual at localbase@proc+current
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc du [val] \\{ \common deflocal@proc .,du,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,du,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
current = $-(localbase@proc)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc
\{ localbytes = current
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
end if \} }
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if qqword eq type
dd ?,?,?,?,?,?,?,?
else if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
macro deflocal@proc name,def,[val] { name def val }
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =?, val \{ ..tmp equ \}
match any (=?), val \{ ..tmp equ \}
match =label, def \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
struc label type { label . type }
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count*2
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
rq count*4
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
rq count*2
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
rq count*4
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match =QQWORD, vartype \\{ label varname qqword
dq ?,?,?,?
restore done@local \\}
match =XWORD, vartype \\{ label varname xword
dq ?,?
restore done@local \\}
match =YWORD, vartype \\{ label varname yword
dq ?,?,?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }

View File

@@ -0,0 +1,240 @@
; Macroinstructions for defining data structures
macro struct name
{ virtual at 0
fields@struct equ name
match child parent, name \{ fields@struct equ child,fields@\#parent \}
sub@struct equ
struc db [val] \{ \common define field@struct .,db,<val>
fields@struct equ fields@struct,field@struct \}
struc dw [val] \{ \common define field@struct .,dw,<val>
fields@struct equ fields@struct,field@struct \}
struc du [val] \{ \common define field@struct .,du,<val>
fields@struct equ fields@struct,field@struct \}
struc dd [val] \{ \common define field@struct .,dd,<val>
fields@struct equ fields@struct,field@struct \}
struc dp [val] \{ \common define field@struct .,dp,<val>
fields@struct equ fields@struct,field@struct \}
struc dq [val] \{ \common define field@struct .,dq,<val>
fields@struct equ fields@struct,field@struct \}
struc dt [val] \{ \common define field@struct .,dt,<val>
fields@struct equ fields@struct,field@struct \}
struc rb count \{ define field@struct .,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rw count \{ define field@struct .,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rd count \{ define field@struct .,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rp count \{ define field@struct .,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rq count \{ define field@struct .,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rt count \{ define field@struct .,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro db [val] \{ \common \local anonymous
define field@struct anonymous,db,<val>
fields@struct equ fields@struct,field@struct \}
macro dw [val] \{ \common \local anonymous
define field@struct anonymous,dw,<val>
fields@struct equ fields@struct,field@struct \}
macro du [val] \{ \common \local anonymous
define field@struct anonymous,du,<val>
fields@struct equ fields@struct,field@struct \}
macro dd [val] \{ \common \local anonymous
define field@struct anonymous,dd,<val>
fields@struct equ fields@struct,field@struct \}
macro dp [val] \{ \common \local anonymous
define field@struct anonymous,dp,<val>
fields@struct equ fields@struct,field@struct \}
macro dq [val] \{ \common \local anonymous
define field@struct anonymous,dq,<val>
fields@struct equ fields@struct,field@struct \}
macro dt [val] \{ \common \local anonymous
define field@struct anonymous,dt,<val>
fields@struct equ fields@struct,field@struct \}
macro rb count \{ \local anonymous
define field@struct anonymous,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rw count \{ \local anonymous
define field@struct anonymous,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rd count \{ \local anonymous
define field@struct anonymous,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rp count \{ \local anonymous
define field@struct anonymous,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rq count \{ \local anonymous
define field@struct anonymous,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rt count \{ \local anonymous
define field@struct anonymous,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro union \{ fields@struct equ fields@struct,,union,<
sub@struct equ union \}
macro struct \{ fields@struct equ fields@struct,,substruct,<
sub@struct equ substruct \} }
macro ends
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
restruc rb,rw,rd,rp,rq,rt
purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt
purge union,struct
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ fields@struct equ
make@struct name,fields
define fields@\\#name fields \\}
end virtual \}
match any, sub@struct \{ fields@struct equ fields@struct> \}
restore sub@struct }
macro make@struct name,[field,type,def]
{ common
local define
define equ name
forward
local sub
match , field \{ make@substruct type,name,sub def
define equ define,.,sub, \}
match any, field \{ define equ define,.#field,type,<def> \}
common
match fields, define \{ define@struct fields \} }
macro define@struct name,[field,type,def]
{ common
virtual
db `name
load initial@struct byte from 0
if initial@struct = '.'
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
err
end if
end virtual
local list
list equ
forward
if ~ field eq .
name#field type def
sizeof.#name#field = $ - name#field
else
label name#.#type
rb sizeof.#type
end if
local value
match any, list \{ list equ list, \}
list equ list <value>
common
sizeof.#name = $
restruc name
match values, list \{
struc name value \\{ \\local \\..base
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
match , fields@struct \\\{ label \\..base
forward
match , value \\\\{ field type def \\\\}
match any, value \\\\{ field type value
if ~ field eq .
rb sizeof.#name#field - ($-field)
end if \\\\}
common label . at \\..base \\\}
\\}
macro name value \\{
match any, fields@struct \\\{ \\\local anonymous
fields@struct equ fields@struct,anonymous,name,<values> \\\}
match , fields@struct \\\{
forward
match , value \\\\{ type def \\\\}
match any, value \\\\{ \\\\local ..field
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
common \\\} \\} \} }
macro enable@substruct
{ macro make@substruct substruct,parent,name,[field,type,def]
\{ \common
\local define
define equ parent,name
\forward
\local sub
match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,parent,sub def
purge make@substruct
define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\}
\common
match fields, define \\{ define@\#substruct fields \\} \} }
enable@substruct
macro define@union parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
virtual at parent#.#name
parent#field type def
sizeof.#parent#field = $ - parent#field
end virtual
if sizeof.#parent#field > $ - parent#.#name
rb sizeof.#parent#field - ($ - parent#.#name)
end if
else
virtual at parent#.#name
label parent#.#type
type def
end virtual
label name#.#type at parent#.#name
if sizeof.#type > $ - parent#.#name
rb sizeof.#type - ($ - parent#.#name)
end if
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name [value] \{ \common
label .\#name
last@union equ
forward
match any, last@union \\{ virtual at .\#name
field type def
end virtual \\}
match , last@union \\{ match , value \\\{ field type def \\\}
match any, value \\\{ field type value \\\} \\}
last@union equ field
common rb sizeof.#name - ($ - .\#name) \}
macro name [value] \{ \common \local ..anonymous
..anonymous name value \} }
macro define@substruct parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
parent#field type def
sizeof.#parent#field = $ - parent#field
else
label parent#.#type
rb sizeof.#type
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name value \{
label .\#name
forward
match , value \\{ field type def \\}
match any, value \\{ field type value
if ~ field eq .
rb sizeof.#parent#field - ($-field)
end if \\}
common \}
macro name value \{ \local ..anonymous
..anonymous name \} }

View File

@@ -0,0 +1,93 @@
import swresample-0, \
ff_float_to_int16_a_sse2,'ff_float_to_int16_a_sse2',\,'ff_float_to_int16_a_sse2',\
ff_float_to_int16_u_sse2,'ff_float_to_int16_u_sse2',\,'ff_float_to_int16_u_sse2',\
ff_float_to_int32_a_sse2,'ff_float_to_int32_a_sse2',\,'ff_float_to_int32_a_sse2',\
ff_float_to_int32_u_sse2,'ff_float_to_int32_u_sse2',\,'ff_float_to_int32_u_sse2',\
ff_int16_to_float_a_sse2,'ff_int16_to_float_a_sse2',\,'ff_int16_to_float_a_sse2',\
ff_int16_to_float_u_sse2,'ff_int16_to_float_u_sse2',\,'ff_int16_to_float_u_sse2',\
ff_int16_to_int32_a_mmx,'ff_int16_to_int32_a_mmx',\,'ff_int16_to_int32_a_mmx',\
ff_int16_to_int32_a_sse2,'ff_int16_to_int32_a_sse2',\,'ff_int16_to_int32_a_sse2',\
ff_int16_to_int32_u_mmx,'ff_int16_to_int32_u_mmx',\,'ff_int16_to_int32_u_mmx',\
ff_int16_to_int32_u_sse2,'ff_int16_to_int32_u_sse2',\,'ff_int16_to_int32_u_sse2',\
ff_int32_to_float_a_sse2,'ff_int32_to_float_a_sse2',\,'ff_int32_to_float_a_sse2',\
ff_int32_to_float_u_sse2,'ff_int32_to_float_u_sse2',\,'ff_int32_to_float_u_sse2',\
ff_int32_to_int16_a_mmx,'ff_int32_to_int16_a_mmx',\,'ff_int32_to_int16_a_mmx',\
ff_int32_to_int16_a_sse2,'ff_int32_to_int16_a_sse2',\,'ff_int32_to_int16_a_sse2',\
ff_int32_to_int16_u_mmx,'ff_int32_to_int16_u_mmx',\,'ff_int32_to_int16_u_mmx',\
ff_int32_to_int16_u_sse2,'ff_int32_to_int16_u_sse2',\,'ff_int32_to_int16_u_sse2',\
ff_log2_tab,'ff_log2_tab',\,'ff_log2_tab',\
ff_mix_1_1_a_float_sse,'ff_mix_1_1_a_float_sse',\,'ff_mix_1_1_a_float_sse',\
ff_mix_1_1_a_int16_mmx,'ff_mix_1_1_a_int16_mmx',\,'ff_mix_1_1_a_int16_mmx',\
ff_mix_1_1_a_int16_sse2,'ff_mix_1_1_a_int16_sse2',\,'ff_mix_1_1_a_int16_sse2',\
ff_mix_1_1_u_float_sse,'ff_mix_1_1_u_float_sse',\,'ff_mix_1_1_u_float_sse',\
ff_mix_1_1_u_int16_mmx,'ff_mix_1_1_u_int16_mmx',\,'ff_mix_1_1_u_int16_mmx',\
ff_mix_1_1_u_int16_sse2,'ff_mix_1_1_u_int16_sse2',\,'ff_mix_1_1_u_int16_sse2',\
ff_mix_2_1_a_float_sse,'ff_mix_2_1_a_float_sse',\,'ff_mix_2_1_a_float_sse',\
ff_mix_2_1_a_int16_mmx,'ff_mix_2_1_a_int16_mmx',\,'ff_mix_2_1_a_int16_mmx',\
ff_mix_2_1_a_int16_sse2,'ff_mix_2_1_a_int16_sse2',\,'ff_mix_2_1_a_int16_sse2',\
ff_mix_2_1_u_float_sse,'ff_mix_2_1_u_float_sse',\,'ff_mix_2_1_u_float_sse',\
ff_mix_2_1_u_int16_mmx,'ff_mix_2_1_u_int16_mmx',\,'ff_mix_2_1_u_int16_mmx',\
ff_mix_2_1_u_int16_sse2,'ff_mix_2_1_u_int16_sse2',\,'ff_mix_2_1_u_int16_sse2',\
ff_pack_2ch_float_to_int16_a_sse2,'ff_pack_2ch_float_to_int16_a_sse2',\,'ff_pack_2ch_float_to_int16_a_sse2',\
ff_pack_2ch_float_to_int16_u_sse2,'ff_pack_2ch_float_to_int16_u_sse2',\,'ff_pack_2ch_float_to_int16_u_sse2',\
ff_pack_2ch_float_to_int32_a_sse2,'ff_pack_2ch_float_to_int32_a_sse2',\,'ff_pack_2ch_float_to_int32_a_sse2',\
ff_pack_2ch_float_to_int32_u_sse2,'ff_pack_2ch_float_to_int32_u_sse2',\,'ff_pack_2ch_float_to_int32_u_sse2',\
ff_pack_2ch_int16_to_float_a_sse2,'ff_pack_2ch_int16_to_float_a_sse2',\,'ff_pack_2ch_int16_to_float_a_sse2',\
ff_pack_2ch_int16_to_float_u_sse2,'ff_pack_2ch_int16_to_float_u_sse2',\,'ff_pack_2ch_int16_to_float_u_sse2',\
ff_pack_2ch_int16_to_int16_a_sse2,'ff_pack_2ch_int16_to_int16_a_sse2',\,'ff_pack_2ch_int16_to_int16_a_sse2',\
ff_pack_2ch_int16_to_int16_u_sse2,'ff_pack_2ch_int16_to_int16_u_sse2',\,'ff_pack_2ch_int16_to_int16_u_sse2',\
ff_pack_2ch_int16_to_int32_a_sse2,'ff_pack_2ch_int16_to_int32_a_sse2',\,'ff_pack_2ch_int16_to_int32_a_sse2',\
ff_pack_2ch_int16_to_int32_u_sse2,'ff_pack_2ch_int16_to_int32_u_sse2',\,'ff_pack_2ch_int16_to_int32_u_sse2',\
ff_pack_2ch_int32_to_float_a_sse2,'ff_pack_2ch_int32_to_float_a_sse2',\,'ff_pack_2ch_int32_to_float_a_sse2',\
ff_pack_2ch_int32_to_float_u_sse2,'ff_pack_2ch_int32_to_float_u_sse2',\,'ff_pack_2ch_int32_to_float_u_sse2',\
ff_pack_2ch_int32_to_int16_a_sse2,'ff_pack_2ch_int32_to_int16_a_sse2',\,'ff_pack_2ch_int32_to_int16_a_sse2',\
ff_pack_2ch_int32_to_int16_u_sse2,'ff_pack_2ch_int32_to_int16_u_sse2',\,'ff_pack_2ch_int32_to_int16_u_sse2',\
ff_pack_2ch_int32_to_int32_a_sse2,'ff_pack_2ch_int32_to_int32_a_sse2',\,'ff_pack_2ch_int32_to_int32_a_sse2',\
ff_pack_2ch_int32_to_int32_u_sse2,'ff_pack_2ch_int32_to_int32_u_sse2',\,'ff_pack_2ch_int32_to_int32_u_sse2',\
ff_pack_6ch_float_to_float_a_mmx,'ff_pack_6ch_float_to_float_a_mmx',\,'ff_pack_6ch_float_to_float_a_mmx',\
ff_pack_6ch_float_to_float_a_sse4,'ff_pack_6ch_float_to_float_a_sse4',\,'ff_pack_6ch_float_to_float_a_sse4',\
ff_pack_6ch_float_to_float_u_mmx,'ff_pack_6ch_float_to_float_u_mmx',\,'ff_pack_6ch_float_to_float_u_mmx',\
ff_pack_6ch_float_to_float_u_sse4,'ff_pack_6ch_float_to_float_u_sse4',\,'ff_pack_6ch_float_to_float_u_sse4',\
ff_pack_6ch_float_to_int32_a_sse4,'ff_pack_6ch_float_to_int32_a_sse4',\,'ff_pack_6ch_float_to_int32_a_sse4',\
ff_pack_6ch_float_to_int32_u_sse4,'ff_pack_6ch_float_to_int32_u_sse4',\,'ff_pack_6ch_float_to_int32_u_sse4',\
ff_pack_6ch_int32_to_float_a_sse4,'ff_pack_6ch_int32_to_float_a_sse4',\,'ff_pack_6ch_int32_to_float_a_sse4',\
ff_pack_6ch_int32_to_float_u_sse4,'ff_pack_6ch_int32_to_float_u_sse4',\,'ff_pack_6ch_int32_to_float_u_sse4',\
ff_resample_int16_rounder,'ff_resample_int16_rounder',\,'ff_resample_int16_rounder',\
ff_unpack_2ch_float_to_int16_a_sse2,'ff_unpack_2ch_float_to_int16_a_sse2',\,'ff_unpack_2ch_float_to_int16_a_sse2',\
ff_unpack_2ch_float_to_int16_u_sse2,'ff_unpack_2ch_float_to_int16_u_sse2',\,'ff_unpack_2ch_float_to_int16_u_sse2',\
ff_unpack_2ch_float_to_int32_a_sse2,'ff_unpack_2ch_float_to_int32_a_sse2',\,'ff_unpack_2ch_float_to_int32_a_sse2',\
ff_unpack_2ch_float_to_int32_u_sse2,'ff_unpack_2ch_float_to_int32_u_sse2',\,'ff_unpack_2ch_float_to_int32_u_sse2',\
ff_unpack_2ch_int16_to_float_a_sse2,'ff_unpack_2ch_int16_to_float_a_sse2',\,'ff_unpack_2ch_int16_to_float_a_sse2',\
ff_unpack_2ch_int16_to_float_a_ssse3,'ff_unpack_2ch_int16_to_float_a_ssse3',\,'ff_unpack_2ch_int16_to_float_a_ssse3',\
ff_unpack_2ch_int16_to_float_u_sse2,'ff_unpack_2ch_int16_to_float_u_sse2',\,'ff_unpack_2ch_int16_to_float_u_sse2',\
ff_unpack_2ch_int16_to_float_u_ssse3,'ff_unpack_2ch_int16_to_float_u_ssse3',\,'ff_unpack_2ch_int16_to_float_u_ssse3',\
ff_unpack_2ch_int16_to_int16_a_sse2,'ff_unpack_2ch_int16_to_int16_a_sse2',\,'ff_unpack_2ch_int16_to_int16_a_sse2',\
ff_unpack_2ch_int16_to_int16_a_ssse3,'ff_unpack_2ch_int16_to_int16_a_ssse3',\,'ff_unpack_2ch_int16_to_int16_a_ssse3',\
ff_unpack_2ch_int16_to_int16_u_sse2,'ff_unpack_2ch_int16_to_int16_u_sse2',\,'ff_unpack_2ch_int16_to_int16_u_sse2',\
ff_unpack_2ch_int16_to_int16_u_ssse3,'ff_unpack_2ch_int16_to_int16_u_ssse3',\,'ff_unpack_2ch_int16_to_int16_u_ssse3',\
ff_unpack_2ch_int16_to_int32_a_sse2,'ff_unpack_2ch_int16_to_int32_a_sse2',\,'ff_unpack_2ch_int16_to_int32_a_sse2',\
ff_unpack_2ch_int16_to_int32_a_ssse3,'ff_unpack_2ch_int16_to_int32_a_ssse3',\,'ff_unpack_2ch_int16_to_int32_a_ssse3',\
ff_unpack_2ch_int16_to_int32_u_sse2,'ff_unpack_2ch_int16_to_int32_u_sse2',\,'ff_unpack_2ch_int16_to_int32_u_sse2',\
ff_unpack_2ch_int16_to_int32_u_ssse3,'ff_unpack_2ch_int16_to_int32_u_ssse3',\,'ff_unpack_2ch_int16_to_int32_u_ssse3',\
ff_unpack_2ch_int32_to_float_a_sse2,'ff_unpack_2ch_int32_to_float_a_sse2',\,'ff_unpack_2ch_int32_to_float_a_sse2',\
ff_unpack_2ch_int32_to_float_u_sse2,'ff_unpack_2ch_int32_to_float_u_sse2',\,'ff_unpack_2ch_int32_to_float_u_sse2',\
ff_unpack_2ch_int32_to_int16_a_sse2,'ff_unpack_2ch_int32_to_int16_a_sse2',\,'ff_unpack_2ch_int32_to_int16_a_sse2',\
ff_unpack_2ch_int32_to_int16_u_sse2,'ff_unpack_2ch_int32_to_int16_u_sse2',\,'ff_unpack_2ch_int32_to_int16_u_sse2',\
ff_unpack_2ch_int32_to_int32_a_sse2,'ff_unpack_2ch_int32_to_int32_a_sse2',\,'ff_unpack_2ch_int32_to_int32_a_sse2',\
ff_unpack_2ch_int32_to_int32_u_sse2,'ff_unpack_2ch_int32_to_int32_u_sse2',\,'ff_unpack_2ch_int32_to_int32_u_sse2',\
swr_alloc,'swr_alloc',\,'swr_alloc',\
swr_alloc_set_opts,'swr_alloc_set_opts',\,'swr_alloc_set_opts',\
swr_convert,'swr_convert',\,'swr_convert',\
swr_drop_output,'swr_drop_output',\,'swr_drop_output',\
swr_free,'swr_free',\,'swr_free',\
swr_get_class,'swr_get_class',\,'swr_get_class',\
swr_get_delay,'swr_get_delay',\,'swr_get_delay',\
swr_init,'swr_init',\,'swr_init',\
swr_inject_silence,'swr_inject_silence',\,'swr_inject_silence',\
swr_next_pts,'swr_next_pts',\,'swr_next_pts',\
swr_set_channel_mapping,'swr_set_channel_mapping',\,'swr_set_channel_mapping',\
swr_set_compensation,'swr_set_compensation',\,'swr_set_compensation',\
swr_set_matrix,'swr_set_matrix',\,'swr_set_matrix',\
swresample_configuration,'swresample_configuration',\,'swresample_configuration',\
swresample_license,'swresample_license',\,'swresample_license',\
swresample_version,'swresample_version',\,'swresample_version'

View File

@@ -0,0 +1,36 @@
import swscale-2,\
sws_addVec,'sws_addVec',\,'sws_addVec',\
sws_allocVec,'sws_allocVec',\,'sws_allocVec',\
sws_alloc_context,'sws_alloc_context',\,'sws_alloc_context',\
sws_cloneVec,'sws_cloneVec',\,'sws_cloneVec',\
sws_context_class,'sws_context_class',\,'sws_context_class',\ DATA
sws_convVec,'sws_convVec',\,'sws_convVec',\
sws_convertPalette8ToPacked24,'sws_convertPalette8ToPacked24',\,'sws_convertPalette8ToPacked24',\
sws_convertPalette8ToPacked32,'sws_convertPalette8ToPacked32',\,'sws_convertPalette8ToPacked32',\
sws_format_name,'sws_format_name',\,'sws_format_name',\
sws_freeContext,'sws_freeContext',\,'sws_freeContext',\
sws_freeFilter,'sws_freeFilter',\,'sws_freeFilter',\
sws_freeVec,'sws_freeVec',\,'sws_freeVec',\
sws_getCachedContext,'sws_getCachedContext',\,'sws_getCachedContext',\
sws_getCoefficients,'sws_getCoefficients',\,'sws_getCoefficients',\
sws_getColorspaceDetails,'sws_getColorspaceDetails',\,'sws_getColorspaceDetails',\
sws_getConstVec,'sws_getConstVec',\,'sws_getConstVec',\
sws_getContext,'sws_getContext',\,'sws_getContext',\
sws_getDefaultFilter,'sws_getDefaultFilter',\,'sws_getDefaultFilter',\
sws_getGaussianVec,'sws_getGaussianVec',\,'sws_getGaussianVec',\
sws_getIdentityVec,'sws_getIdentityVec',\,'sws_getIdentityVec',\
sws_get_class,'sws_get_class',\,'sws_get_class',\
sws_init_context,'sws_init_context',\,'sws_init_context',\
sws_isSupportedInput,'sws_isSupportedInput',\,'sws_isSupportedInput',\
sws_isSupportedOutput,'sws_isSupportedOutput',\,'sws_isSupportedOutput',\
sws_normalizeVec,'sws_normalizeVec',\,'sws_normalizeVec',\
sws_printVec2,'sws_printVec2',\,'sws_printVec2',\
sws_rgb2rgb_init,'sws_rgb2rgb_init',\,'sws_rgb2rgb_init',\
sws_scale,'sws_scale',\,'sws_scale',\
sws_scaleVec,'sws_scaleVec',\,'sws_scaleVec',\
sws_setColorspaceDetails,'sws_setColorspaceDetails',\,'sws_setColorspaceDetails',\
sws_shiftVec,'sws_shiftVec',\,'sws_shiftVec',\
sws_subVec,'sws_subVec',\,'sws_subVec',\
swscale_configuration,'swscale_configuration',\,'swscale_configuration',\
swscale_license,'swscale_license',\,'swscale_license',\
swscale_version,'swscale_version',\,'swscale_version'

View File

@@ -0,0 +1,66 @@
import zlib,\
zlibVersion,'zlibVersion',\
deflate,'deflate',\
deflateEnd,'deflateEnd',\
inflate,'inflate',\
inflateEnd,'inflateEnd',\
deflateSetDictionary,'deflateSetDictionary',\
deflateCopy,'deflateCopy',\
deflateReset,'deflateReset',\
deflateParams,'deflateParams',\
deflateTune,'deflateTune',\
deflateBound,'deflateBound',\
deflatePrime,'deflatePrime',\
deflateSetHeader,'deflateSetHeader',\
inflateSetDictionary,'inflateSetDictionary',\
inflateSync,'inflateSync',\
inflateCopy,'inflateCopy',\
inflateReset,'inflateReset',\
inflateReset2,'inflateReset2',\
inflatePrime,'inflatePrime',\
inflateMark,'inflateMark',\
inflateGetHeader,'inflateGetHeader',\
inflateBack,'inflateBack',\
inflateBackEnd,'inflateBackEnd',\
zlibCompileFlags,'zlibCompileFlags',\
compress,'compress',\
compress2,'compress2',\
compressBound,'compressBound',\
uncompress,'uncompress',\
gzopen,'gzopen',\
gzdopen,'gzdopen',\
gzbuffer,'gzbuffer',\
gzsetparams,'gzsetparams',\
gzread,'gzread',\
gzwrite,'gzwrite',\
gzprintf,'gzprintf',\
gzputs,'gzputs',\
gzgets,'gzgets',\
gzputc,'gzputc',\
gzgetc,'gzgetc',\
gzungetc,'gzungetc',\
gzflush,'gzflush',\
gzseek,'gzseek',\
gzrewind,'gzrewind',\
gztell,'gztell',\
gzoffset,'gzoffset',\
gzeof,'gzeof',\
gzdirect,'gzdirect',\
gzclose,'gzclose',\
gzclose_r,'gzclose_r',\
gzclose_w,'gzclose_w',\
gzerror,'gzerror',\
gzclearerr,'gzclearerr',\
adler32,'adler32',\
crc32,'crc32',\
adler32_combine,'adler32_combine',\
crc32_combine,'crc32_combine',\
deflateInit_,'deflateInit_',\
deflateInit2_,'deflateInit2_',\
inflateInit_,'inflateInit_',\
inflateInit2_,'inflateInit2_',\
inflateBackInit_,'inflateBackInit_',\
zError,'zError',\
inflateSyncPoint,'inflateSyncPoint',\
get_crc_table,'get_crc_table',\
inflateUndermine,'inflateUndermine'

667
contrib/sdk/fasm/mpg123.asm Normal file
View File

@@ -0,0 +1,667 @@
STACK_SIZE equ 4096
include "include/app.inc"
align 8
main:
.argc equ ebp+8
.argv equ ebp+12
.envp equ ebp+16
; int3
push ebp
mov ebp, esp
push ebx
mov eax, [.argc]
cmp eax, 2
jae @F
call _get_moviefile
mov [input_file], eax
@@:
call [mpg123_init]
test eax, eax
jz @F
push eax
call [mpg123_plain_strerror]
mov [esp], eax
push msg_init_fail
call [_printf]
add esp, 4
jmp .fail
@@:
push dword error
push 0
call [mpg123_new]
add esp, 8
mov [mh], eax
mov ebx, eax
test eax, eax
jz .err_1
push [input_file]
push eax
call [mpg123_open]
add esp, 8
test eax, eax
jnz .err_1
push encoding
push channels
push rate
push ebx
call [mpg123_getformat]
add esp, 16
test eax, eax
jnz .err_1
push ebx
call [mpg123_scan]
test eax, eax
jz @F
call [mpg123_strerror]
mov [esp], eax
push msg_print
call [_printf]
add esp, 8
jmp .fail
@@:
call [mpg123_format_none]
mov ecx, [encoding]
mov [esp], ecx
push [channels]
push [rate]
push ebx
call [mpg123_format]
add esp, 16
push error
stdcall InitSound
test eax, eax
jz @F
cinvoke _printf, msg_sound
jmp .fail
@@:
mov eax, [rate]
mov ecx, [channels]
mov [whdr.riff_id], 0x46464952
mov [whdr.riff_format], 0x45564157
mov [whdr.wFormatTag], 0x01
mov [whdr.nSamplesPerSec], eax
mov [whdr.nChannels], cx
mov [whdr.wBitsPerSample], 16
stdcall test_wav, whdr
stdcall CreateBuffer, eax, 0, hBuff
test eax, eax
jz @F
cinvoke _printf, msg_buffer
jmp .fail
@@:
mov eax, [hBuff]
push esi
push edi
mov ecx, 0x40000
mov eax, 68
mov ebx, 12
int 0x40
push eax ;buffer esp+16
push count ;&count esp+12
push 0x40000 ;remain esp+8
push eax ;outPtr esp+4
push [mh] ;mh esp
xor ebx, ebx ;totalcount
.inner:
; int3
mov [count], 0
call [mpg123_read]
mov ebx, [count]
test eax, eax
jz @F
test ebx, ebx
jz .done
@@:
.write_out:
add ebx, 4095
and ebx, -4096
mov esi, [esp+16]
stdcall WaveOut, [hBuff], esi, ebx
mov [esp+8], dword 0x40000
mov edi, [esp+16]
mov [esp+4], edi
jmp .inner
.done:
mov edi, [esp+16]
mov ecx, 4096
xor eax, eax
rep stosd
mov esi, [esp+16]
stdcall WaveOut, [hBuff], esi, 16384
add esp, 20
pop edi
pop esi
xor eax, eax
pop ebx
mov esp, ebp
pop ebp
ret
.err_1:
test ebx, ebx
jnz @F
push [error]
call [mpg123_plain_strerror]
jmp .err_2
@@:
push ebx
call [mpg123_strerror]
.err_2:
mov [esp], eax
push msg_trouble
call [_printf]
add esp, 8
.fail:
mov eax, -1
pop ebx
mov esp, ebp
pop ebp
ret
align 4
getprocaddress:
mov edx, [esp + 8] ; hlib
xor eax, eax
test edx, edx ; If hlib = 0 then goto .end
jz .end
.next:
cmp [edx], dword 0 ; If end of export table then goto .end
jz .end
xor eax, eax
mov esi, [edx]
mov edi, [esp + 4] ; name
.next_:
lodsb
scasb
jne .fail
or al, al
jnz .next_
jmp .ok
.fail:
add edx, 8
jmp .next
.ok: ; return address
mov eax, [edx + 4]
.end:
ret 8
align 8
_get_moviefile:
pushad
mov eax, 68
mov ebx, 19
mov ecx, sz_proc_lib
int 0x40
mov [proclib], eax
test eax, eax
jz .fail
push [proclib]
push sz_OpenDialog_init
call getprocaddress
mov [opendialog_init], eax
push dword[proclib]
push sz_OpenDialog_start
call getprocaddress
mov [opendialog_start], eax
mov eax, 68
mov ebx, 12
mov ecx, 4096*3
int 0x40
mov [od.procinfo], eax
add eax, 1024
mov [od.filename_area], eax
add eax, 3072
mov [od.opendir_path], eax
add eax, 4096
mov [od.openfile_path], eax
push od
call [opendialog_init]
mov eax, [od.openfile_path]
mov [eax], byte 0 ; end of ASCIIZ-string(may be don't need?)
push od
call [opendialog_start]
popad
mov eax, [od.openfile_path]; selected filePath
ret
.fail:
xor eax, eax
ret
align 4
fake_on_redraw:
ret
SRV_GETVERSION equ 0
SND_CREATE_BUFF equ 1
SND_DESTROY_BUFF equ 2
SND_SETFORMAT equ 3
SND_GETFORMAT equ 4
SND_RESET equ 5
SND_SETPOS equ 6
SND_GETPOS equ 7
SND_SETBUFF equ 8
SND_OUT equ 9
SND_PLAY equ 10
SND_STOP equ 11
SND_SETVOLUME equ 12
SND_GETVOLUME equ 13
SND_SETPAN equ 14
SND_GETPAN equ 15
SND_GETBUFFSIZE equ 16
SND_GETFREESPACE equ 17
SND_SETTIMEBASE equ 18
SND_GETTIMESTAMP equ 19
align 4
InitSound: ;p_ver:dword
push ebx
push ecx
mov eax, 68
mov ebx, 16
mov ecx, szInfinity
int 0x40
mov [hSound], eax
test eax, eax
jz .fail
mov eax, 68
mov ebx, 16
mov ecx, szSound
int 0x40
mov [hrdwSound], eax
lea eax, [esp+12] ;p_ver
xor ebx, ebx
push 4 ;.out_size
push eax ;.output
push ebx ;.inp_size
push ebx ;.input
push SRV_GETVERSION ;.code
push [hSound] ;.handle
mov eax, 68
mov ebx, 17
mov ecx, esp ;[handle]
int 0x40
add esp, 24
pop ecx
pop ebx
ret 4
.fail:
or eax, -1
pop ecx
pop ebx
ret 4
align 4
CreateBuffer: ;format:dword,size:dword,p_str:dword
push ebx
push ecx
lea eax, [esp+20] ;p_str
lea ebx, [esp+12] ;format
push 4 ;.out_size
push eax ;.output
push 8 ;.inp_size
push ebx ;.input
push SND_CREATE_BUFF;.code
push [hSound] ;.handle
mov eax, 68
mov ebx, 17
mov ecx, esp
int 0x40
add esp, 24 ;io_cintrol
pop ecx
pop ebx
ret 12
align 4
proc test_wav stdcall, hdr:dword
mov eax, [hdr]
cmp dword [eax], 0x46464952
jne .fail
cmp dword [eax+8], 0x45564157
jne .fail
cmp word [eax+20], 1
jne .fail
mov ecx, dword [eax+24]
mov edx, 22050
cmp ecx, edx
ja .high
je .l_22
cmp ecx, 8000
je .l_8
cmp ecx, 11025
je .l_11
cmp ecx, 12000
je .l_12
cmp ecx, 16000
je .l_16
.fail:
xor eax, eax
ret
.high:
cmp ecx, 24000
je .LN56
cmp ecx, 32000
je .LN65
cmp ecx, 44100
je .LN74
cmp ecx, 48000
jne .fail
movzx ecx, word [eax+22]
dec ecx
je .LN79
dec ecx
jne .LN74
mov edx, 19
jmp .done
.LN79:
mov edx, 20
jmp .done
.LN74:
movzx ecx, word [eax+22]
dec ecx
je .LN70
dec ecx
jne .LN65
mov edx, 21
jmp .done
.LN70:
mov edx, 22
jmp .done
.LN65:
movzx ecx, word [eax+22]
dec ecx
je .LN61
dec ecx
jne .LN56
mov edx, 23
jmp .done
.LN61:
mov edx, 24
jmp .done
.LN56:
movzx ecx, word [eax+22]
dec ecx
je .LN52
dec ecx
je .LN50
.l_22:
movzx ecx, word [eax+22]
dec ecx
je .LN43
dec ecx
je .LN41
.l_16:
movzx ecx, word [eax+22]
dec ecx
je .LN34
dec ecx
je .LN32
.l_12:
movzx ecx, word [eax+22]
dec ecx
je .LN25
dec ecx
je .LN23
.l_11:
movzx ecx, word [eax+22]
dec ecx
je .LN16
dec ecx
je .LN14
.l_8:
movzx ecx, word [eax+22]
dec ecx
je .LN7
dec ecx
jne .fail
mov edx, 35
jmp .done
.LN7:
mov edx, 36
jmp .done
.LN14:
mov edx, 33
jmp .done
.LN16:
mov edx, 34
jmp .done
.LN23:
mov edx, 31
jmp .done
.LN25:
mov edx, 32
jmp .done
.LN32:
mov edx, 29
jmp .done
.LN34:
mov edx, 30
jmp .done
.LN41:
mov edx, 27
jmp .done
.LN43:
mov edx, 28
jmp .done
.LN50:
mov edx, 25
jmp .done
.LN52:
mov edx, 26
.done:
xor ecx, ecx
cmp word [eax+34], 16
setne cl
dec ecx
and ecx, -18
add ecx, edx
mov eax, ecx
ret
endp
align 4
WaveOut: ;str:dword, src:dword, size:dword
push ebx
push ecx
xor eax, eax
lea ebx, [esp+12] ;[stream]
push eax ;.out_size
push eax ;.output
push 12 ;.inp_size
push ebx ;.input
push SND_OUT ;.code
push dword [hSound] ;.handle
mov eax, 68
mov ebx, 17
mov ecx, esp
int 0x40
add esp, 24
pop ecx
pop ebx
ret 12
align 4
hSound dd ?
hrdwSound dd ?
szInfinity db 'INFINITY',0
szSound db 'SOUND',0
align 4
od:
.mode dd 0
.procinfo dd 0
.com_area_name dd sz_com_area_name
.com_area dd 0
.opendir_path dd 0
.dir_default_path dd sz_dir_default_path
.start_path dd sz_start_path
.draw_window dd fake_on_redraw
.status dd 0
.openfile_path dd 0
.filename_area dd 0
.filter_area dd filefilter
.x_size dw 512
.x_start dw 512
.y_size dw 512
.y_start dw 512
filefilter:
dd filefilter.end - filefilter
db 'mp3',0
; db 'flv',0
; db 'mov',0
; db 'mpg',0
; db 'mpeg',0
; db 'mkv',0
; db 'mp4',0
; db 'webm',0
; db 'wmv',0
.end:
db 0
sz_proc_lib db "/rd/1/lib/proc_lib.obj",0
sz_OpenDialog_init db "OpenDialog_init",0
sz_OpenDialog_start db "OpenDialog_start",0
sz_com_area_name db "FFFFFFFF_open_dialog",0
sz_dir_default_path db "/rd/1",0
sz_start_path db "/rd/1/File managers/opendial",0
msg_print db '%s',0x0D,0x0A,0
msg_init_fail db 'Cannot initialize mpg123 library: %s', 0x0D,0x0A,0
msg_trouble db 'Trouble with mpg123: %s', 0x0D,0x0A,0
msg_sound db 'Sound service not installed', 0x0D,0x0A,0
msg_buffer db 'Unable to create a sound buffer',0x0D,0x0A,0
align 16
__idata_start:
library libc,'libc.dll', \
libmpg123, 'libmpg123.dll'
include 'include/libc.inc'
include 'include/libmpg123.inc'
__idata_end:
__iend:
align 4
whdr:
.riff_id rd 1
.riff_size rd 1
.riff_format rd 1
.fmt_id rd 1
.fmt_size rd 1
.wFormatTag rw 1
.nChannels rw 1
.nSamplesPerSec rd 1
.nAvgBytesPerSec rd 1
.nBlockAlign rw 1
.wBitsPerSample rw 1
.data_id rd 1
.data_size rd 1
proclib rd 1
opendialog_init rd 1
opendialog_start rd 1
input_file rd 1
mh rd 1
encoding rd 1
channels rd 1
rate rd 1
hBuff rd 1
count rd 1
done rd 1
error rd 1
__cmdline: rb 256
__pgmname: rb 1024
rb 16
__stack:
__bssend:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "GL/osmesa.h"
#include "GL/glu.h"
#define XK_Left 176
#define XK_Right 179
#define XK_Up 178
#define XK_Down 177
extern GLfloat view_rotx, view_roty, view_rotz;
GLint gear1, gear2, gear3;
extern GLfloat angle;
static void gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
GLint teeth, GLfloat tooth_depth)
{
GLint i;
GLfloat r0, r1, r2;
GLfloat angle, da;
GLfloat u, v, len;
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0;
r2 = outer_radius + tooth_depth / 2.0;
da = 2.0 * M_PI / teeth / 4.0;
glShadeModel(GL_FLAT);
glNormal3f(0.0, 0.0, 1.0);
/* draw front face */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
if (i < teeth) {
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
width * 0.5);
}
}
glEnd();
/* draw front sides of teeth */
glBegin(GL_QUADS);
da = 2.0 * M_PI / teeth / 4.0;
for (i = 0; i < teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
width * 0.5);
}
glEnd();
glNormal3f(0.0, 0.0, -1.0);
/* draw back face */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
if (i < teeth) {
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
-width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
}
}
glEnd();
/* draw back sides of teeth */
glBegin(GL_QUADS);
da = 2.0 * M_PI / teeth / 4.0;
for (i = 0; i < teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
-width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
-width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
}
glEnd();
/* draw outward faces of teeth */
glBegin(GL_QUAD_STRIP);
for (i = 0; i < teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
u = r2 * cos(angle + da) - r1 * cos(angle);
v = r2 * sin(angle + da) - r1 * sin(angle);
len = sqrt(u * u + v * v);
u /= len;
v /= len;
glNormal3f(v, -u, 0.0);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
glNormal3f(cos(angle), sin(angle), 0.0);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
-width * 0.5);
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
glNormal3f(v, -u, 0.0);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
-width * 0.5);
glNormal3f(cos(angle), sin(angle), 0.0);
}
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
glEnd();
glShadeModel(GL_SMOOTH);
/* draw inside radius cylinder */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glNormal3f(-cos(angle), -sin(angle), 0.0);
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
}
glEnd();
}
void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1.0, 0.0, 0.0);
glRotatef(view_roty, 0.0, 1.0, 0.0);
glRotatef(view_rotz, 0.0, 0.0, 1.0);
glPushMatrix();
glTranslatef(-3.0, -2.0, 0.0);
glRotatef(angle, 0.0, 0.0, 1.0);
glCallList(gear1);
glPopMatrix();
glPushMatrix();
glTranslatef(3.1, -2.0, 0.0);
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
glCallList(gear2);
glPopMatrix();
glPushMatrix();
glTranslatef(-3.1, 4.2, 0.0);
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
glCallList(gear3);
glPopMatrix();
glPopMatrix();
}
/* new window size or exposure */
void Reshape(int width, int height)
{
glViewport(0, 0, (GLint) width, (GLint) height);
GLfloat h = (GLfloat) height / (GLfloat) width;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -40.0);
}
void Init(void)
{
static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
/* make the gears */
gear1 = glGenLists(1);
glNewList(gear1, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
gear(1.0, 4.0, 1.0, 20, 0.7);
glEndList();
gear2 = glGenLists(1);
glNewList(gear2, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
gear(0.5, 2.0, 2.0, 10, 0.7);
glEndList();
gear3 = glGenLists(1);
glNewList(gear3, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
gear(1.3, 2.0, 0.5, 10, 0.7);
glEndList();
glEnable(GL_NORMALIZE);
}
void Key(unsigned char code, int x, int y)
{
int i;
(void) x; (void) y;
if (code == XK_Left) {
view_roty += 5.0;
}
else if (code == XK_Right) {
view_roty -= 5.0;
}
else if (code == XK_Up) {
view_rotx += 5.0;
}
else if (code == XK_Down) {
view_rotx -= 5.0;
}
};
void Idle(void)
{
angle += 70.0 * 0.05; /* 70 degrees per second */
if (angle > 3600.0)
angle -= 3600.0;
}

View File

@@ -0,0 +1,48 @@
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice including the dates of first publication and
* either this permission notice or a reference to
* http://oss.sgi.com/projects/FreeB/
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of Silicon Graphics, Inc.
* shall not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization from
* Silicon Graphics, Inc.
*/
#ifndef __gluint_h__
#define __gluint_h__
extern const unsigned char *__gluNURBSErrorString( int errnum );
extern const unsigned char *__gluTessErrorString( int errnum );
#ifdef _EXTENSIONS_
#define COS cosf
#define SIN sinf
#define SQRT sqrtf
#else
#define COS cos
#define SIN sin
#define SQRT sqrt
#endif
#endif /* __gluint_h__ */

View File

@@ -0,0 +1,72 @@
/*
** gluos.h - operating system dependencies for GLU
**
*/
#ifdef __VMS
#ifdef __cplusplus
#pragma message disable nocordel
#pragma message disable codeunreachable
#pragma message disable codcauunr
#endif
#endif
#ifdef __WATCOMC__
/* Disable *lots* of warnings to get a clean build. I can't be bothered fixing the
* code at the moment, as it is pretty ugly.
*/
#pragma warning 7 10
#pragma warning 13 10
#pragma warning 14 10
#pragma warning 367 10
#pragma warning 379 10
#pragma warning 726 10
#pragma warning 836 10
#endif
#ifdef BUILD_FOR_SNAP
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#elif defined(_WIN32)
#include <stdlib.h> /* For _MAX_PATH definition */
#include <stdio.h>
#include <malloc.h>
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define NOIME
#define NOMINMAX
#define _WIN32_WINNT 0x0400
#ifndef STRICT
#define STRICT 1
#endif
#include <windows.h>
/* Disable warnings */
#pragma warning(disable : 4101)
#pragma warning(disable : 4244)
#pragma warning(disable : 4761)
#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1300
#pragma comment(linker, "/OPT:NOWIN98")
#endif
#elif defined(__OS2__)
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#define WINGDIAPI
#else
/* Disable Microsoft-specific keywords */
//#define GLAPIENTRY
//#define WINGDIAPI
#endif

View File

@@ -0,0 +1,610 @@
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
/**
(c) Copyright 1993, Silicon Graphics, Inc.
ALL RIGHTS RESERVED
Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that
both the copyright notice and this permission notice appear in
supporting documentation, and that the name of Silicon
Graphics, Inc. not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission.
THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
PERFORMANCE OF THIS SOFTWARE.
US Government Users Restricted Rights
Use, duplication, or disclosure by the Government is subject to
restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
(c)(1)(ii) of the Rights in Technical Data and Computer
Software clause at DFARS 252.227-7013 and/or in similar or
successor clauses in the FAR or the DOD or NASA FAR
Supplement. Unpublished-- rights reserved under the copyright
laws of the United States. Contractor/manufacturer is Silicon
Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
94039-7311.
OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#include <math.h>
#include "gluos.h"
#include "gluint.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
//#include "glutint.h"
#define GLUTAPIENTRY
/* Some <math.h> files do not define M_PI... */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
static GLUquadricObj *quadObj;
#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
static void
initQuadObj(void)
{
quadObj = gluNewQuadric();
if (!quadObj)
{
printf("%s: out of memory.\n", __FUNCTION__);
abort();
};
// __glutFatalError("out of memory.");
}
/* CENTRY */
void GLUTAPIENTRY
glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
void GLUTAPIENTRY
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
void GLUTAPIENTRY
glutWireCone(GLdouble base, GLdouble height,
GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
}
void GLUTAPIENTRY
glutSolidCone(GLdouble base, GLdouble height,
GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluCylinder(quadObj, base, 0.0, height, slices, stacks);
}
/* ENDCENTRY */
static void
drawBox(GLfloat size, GLenum type)
{
static GLfloat n[6][3] =
{
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
static GLint faces[6][4] =
{
{0, 1, 2, 3},
{3, 2, 6, 7},
{7, 6, 5, 4},
{4, 5, 1, 0},
{5, 6, 2, 1},
{7, 4, 0, 3}
};
GLfloat v[8][3];
GLint i;
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
for (i = 5; i >= 0; i--) {
glBegin(type);
glNormal3fv(&n[i][0]);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glEnd();
}
}
/* CENTRY */
void GLUTAPIENTRY
glutWireCube(GLdouble size)
{
drawBox(size, GL_LINE_LOOP);
}
void GLUTAPIENTRY
glutSolidCube(GLdouble size)
{
drawBox(size, GL_QUADS);
}
/* ENDCENTRY */
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
/* CENTRY */
void GLUTAPIENTRY
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
glPushAttrib(GL_POLYGON_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
doughnut(innerRadius, outerRadius, nsides, rings);
glPopAttrib();
}
void GLUTAPIENTRY
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
doughnut(innerRadius, outerRadius, nsides, rings);
}
/* ENDCENTRY */
static GLfloat dodec[20][3];
static void
initDodecahedron(void)
{
GLfloat alpha, beta;
alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
/* *INDENT-OFF* */
dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
/* *INDENT-ON* */
}
#define DIFF3(_a,_b,_c) { \
(_c)[0] = (_a)[0] - (_b)[0]; \
(_c)[1] = (_a)[1] - (_b)[1]; \
(_c)[2] = (_a)[2] - (_b)[2]; \
}
static void
crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
{
GLfloat p[3]; /* in case prod == v1 or v2 */
p[0] = v1[1] * v2[2] - v2[1] * v1[2];
p[1] = v1[2] * v2[0] - v2[2] * v1[0];
p[2] = v1[0] * v2[1] - v2[0] * v1[1];
prod[0] = p[0];
prod[1] = p[1];
prod[2] = p[2];
}
static void
normalize(GLfloat v[3])
{
GLfloat d;
d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (d == 0.0) {
// __glutWarning("normalize: zero length vector");
v[0] = d = 1.0;
}
d = 1 / d;
v[0] *= d;
v[1] *= d;
v[2] *= d;
}
static void
pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
{
GLfloat n0[3], d1[3], d2[3];
DIFF3(dodec[a], dodec[b], d1);
DIFF3(dodec[b], dodec[c], d2);
crossprod(d1, d2, n0);
normalize(n0);
glBegin(shadeType);
glNormal3fv(n0);
glVertex3fv(&dodec[a][0]);
glVertex3fv(&dodec[b][0]);
glVertex3fv(&dodec[c][0]);
glVertex3fv(&dodec[d][0]);
glVertex3fv(&dodec[e][0]);
glEnd();
}
static void
dodecahedron(GLenum type)
{
static int inited = 0;
if (inited == 0) {
inited = 1;
initDodecahedron();
}
pentagon(0, 1, 9, 16, 5, type);
pentagon(1, 0, 3, 18, 7, type);
pentagon(1, 7, 11, 10, 9, type);
pentagon(11, 7, 18, 19, 6, type);
pentagon(8, 17, 16, 9, 10, type);
pentagon(2, 14, 15, 6, 19, type);
pentagon(2, 13, 12, 4, 14, type);
pentagon(2, 19, 18, 3, 13, type);
pentagon(3, 0, 5, 12, 13, type);
pentagon(6, 15, 8, 10, 11, type);
pentagon(4, 17, 8, 15, 14, type);
pentagon(4, 12, 5, 16, 17, type);
}
/* CENTRY */
void GLUTAPIENTRY
glutWireDodecahedron(void)
{
dodecahedron(GL_LINE_LOOP);
}
void GLUTAPIENTRY
glutSolidDodecahedron(void)
{
dodecahedron(GL_TRIANGLE_FAN);
}
/* ENDCENTRY */
static void
recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
GLenum shadeType)
{
GLfloat q0[3], q1[3];
DIFF3(n1, n2, q0);
DIFF3(n2, n3, q1);
crossprod(q0, q1, q1);
normalize(q1);
glBegin(shadeType);
glNormal3fv(q1);
glVertex3fv(n1);
glVertex3fv(n2);
glVertex3fv(n3);
glEnd();
}
static void
subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
GLenum shadeType)
{
int depth;
GLfloat w0[3], w1[3], w2[3];
GLfloat l;
int i, j, k, n;
depth = 1;
for (i = 0; i < depth; i++) {
for (j = 0; i + j < depth; j++) {
k = depth - i - j;
for (n = 0; n < 3; n++) {
w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
/ depth;
w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
/ depth;
}
l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
w0[0] /= l;
w0[1] /= l;
w0[2] /= l;
l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
w1[0] /= l;
w1[1] /= l;
w1[2] /= l;
l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
w2[0] /= l;
w2[1] /= l;
w2[2] /= l;
recorditem(w1, w0, w2, shadeType);
}
}
}
static void
drawtriangle(int i, GLfloat data[][3], int ndx[][3],
GLenum shadeType)
{
GLfloat *x0, *x1, *x2;
x0 = data[ndx[i][0]];
x1 = data[ndx[i][1]];
x2 = data[ndx[i][2]];
subdivide(x0, x1, x2, shadeType);
}
/* octahedron data: The octahedron produced is centered at the
origin and has radius 1.0 */
static GLfloat odata[6][3] =
{
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
static int ondex[8][3] =
{
{0, 4, 2},
{1, 2, 4},
{0, 3, 4},
{1, 4, 3},
{0, 2, 5},
{1, 5, 2},
{0, 5, 3},
{1, 3, 5}
};
static void
octahedron(GLenum shadeType)
{
int i;
for (i = 7; i >= 0; i--) {
drawtriangle(i, odata, ondex, shadeType);
}
}
/* CENTRY */
void GLUTAPIENTRY
glutWireOctahedron(void)
{
octahedron(GL_LINE_LOOP);
}
void GLUTAPIENTRY
glutSolidOctahedron(void)
{
octahedron(GL_TRIANGLES);
}
/* ENDCENTRY */
/* icosahedron data: These numbers are rigged to make an
icosahedron of radius 1.0 */
#define X .525731112119133606
#define Z .850650808352039932
static GLfloat idata[12][3] =
{
{-X, 0, Z},
{X, 0, Z},
{-X, 0, -Z},
{X, 0, -Z},
{0, Z, X},
{0, Z, -X},
{0, -Z, X},
{0, -Z, -X},
{Z, X, 0},
{-Z, X, 0},
{Z, -X, 0},
{-Z, -X, 0}
};
static int index[20][3] =
{
{0, 4, 1},
{0, 9, 4},
{9, 5, 4},
{4, 5, 8},
{4, 8, 1},
{8, 10, 1},
{8, 3, 10},
{5, 3, 8},
{5, 2, 3},
{2, 7, 3},
{7, 10, 3},
{7, 6, 10},
{7, 11, 6},
{11, 0, 6},
{0, 1, 6},
{6, 1, 10},
{9, 0, 11},
{9, 11, 2},
{9, 2, 5},
{7, 2, 11},
};
static void
icosahedron(GLenum shadeType)
{
int i;
for (i = 19; i >= 0; i--) {
drawtriangle(i, idata, index, shadeType);
}
}
/* CENTRY */
void GLUTAPIENTRY
glutWireIcosahedron(void)
{
icosahedron(GL_LINE_LOOP);
}
void GLUTAPIENTRY
glutSolidIcosahedron(void)
{
icosahedron(GL_TRIANGLES);
}
/* ENDCENTRY */
/* tetrahedron data: */
#define T 1.73205080756887729
static GLfloat tdata[4][3] =
{
{T, T, T},
{T, -T, -T},
{-T, T, -T},
{-T, -T, T}
};
static int tndex[4][3] =
{
{0, 1, 3},
{2, 1, 0},
{3, 2, 0},
{1, 2, 3}
};
static void
tetrahedron(GLenum shadeType)
{
int i;
for (i = 3; i >= 0; i--)
drawtriangle(i, tdata, tndex, shadeType);
}
/* CENTRY */
void GLUTAPIENTRY
glutWireTetrahedron(void)
{
tetrahedron(GL_LINE_LOOP);
}
void GLUTAPIENTRY
glutSolidTetrahedron(void)
{
tetrahedron(GL_TRIANGLES);
}
/* ENDCENTRY */

View File

@@ -0,0 +1,798 @@
#ifndef __glutint_h__
#define __glutint_h__
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
#ifdef __VMS
#include <GL/vms_x_fix.h>
#endif
#if defined(__CYGWIN32__)
#include <sys/time.h>
#endif
#define SUPPORT_FORTRAN /* With GLUT 3.7, everyone supports Fortran. */
#if defined(_WIN32)
#include "glutwin32.h"
#else
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#endif
#ifndef GLUT_BUILDING_LIB
#define GLUT_BUILDING_LIB /* Building the GLUT library itself. */
#endif
#include <GL/glut.h>
#ifndef _WIN32
/* added by BrianP: */
#ifndef APIENTRY
#define APIENTRY GLAPIENTRY
#endif
#define __cdecl GLAPIENTRY
#define CDECL GLAPIENTRY
#endif
/* GLUT_BUILDING_LIB is used by <GL/glut.h> to 1) not #pragma link
with the GLUT library, and 2) avoid the Win32 atexit hack. */
#ifdef SUPPORT_FORTRAN
#include <GL/glutf90.h>
#endif
#ifdef __vms
#if ( __VMS_VER < 70000000 )
#define OLD_VMS
struct timeval6 {
__int64 val;
};
extern int sys$gettim(struct timeval6 *);
#else
#include <time.h>
#endif
#else
#include <sys/types.h>
#if !defined(_WIN32) || defined(__CYGWIN32__)
#include <sys/time.h>
#else
#include <winsock.h>
#endif
#endif
#if defined(__vms) && ( __VMS_VER < 70000000 )
/* For VMS6.2 or lower :
One TICK on VMS is 100 nanoseconds; 0.1 microseconds or
0.0001 milliseconds. This means that there are 0.01
ticks/ns, 10 ticks/us, 10,000 ticks/ms and 10,000,000
ticks/second. */
#define TICKS_PER_MILLISECOND 10000
#define TICKS_PER_SECOND 10000000
#define GETTIMEOFDAY(_x) (void) sys$gettim (_x);
#define ADD_TIME(dest, src1, src2) { \
(dest).val = (src1).val + (src2).val; \
}
#define TIMEDELTA(dest, src1, src2) { \
(dest).val = (src1).val - (src2).val; \
}
#define IS_AFTER(t1, t2) ((t2).val > (t1).val)
#define IS_AT_OR_AFTER(t1, t2) ((t2).val >= (t1).val)
#else
#if defined(SVR4) && !defined(sun) /* Sun claims SVR4, but
wants 2 args. */
#define GETTIMEOFDAY(_x) gettimeofday(_x)
#else
#define GETTIMEOFDAY(_x) gettimeofday(_x, NULL)
#endif
#define ADD_TIME(dest, src1, src2) { \
if(((dest).tv_usec = \
(src1).tv_usec + (src2).tv_usec) >= 1000000) { \
(dest).tv_usec -= 1000000; \
(dest).tv_sec = (src1).tv_sec + (src2).tv_sec + 1; \
} else { \
(dest).tv_sec = (src1).tv_sec + (src2).tv_sec; \
if(((dest).tv_sec >= 1) && (((dest).tv_usec <0))) { \
(dest).tv_sec --;(dest).tv_usec += 1000000; \
} \
} \
}
#define TIMEDELTA(dest, src1, src2) { \
if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) { \
(dest).tv_usec += 1000000; \
(dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1; \
} else { \
(dest).tv_sec = (src1).tv_sec - (src2).tv_sec; \
} \
}
#define IS_AFTER(t1, t2) \
(((t2).tv_sec > (t1).tv_sec) || \
(((t2).tv_sec == (t1).tv_sec) && \
((t2).tv_usec > (t1).tv_usec)))
#define IS_AT_OR_AFTER(t1, t2) \
(((t2).tv_sec > (t1).tv_sec) || \
(((t2).tv_sec == (t1).tv_sec) && \
((t2).tv_usec >= (t1).tv_usec)))
#endif
#define IGNORE_IN_GAME_MODE() \
{ if (__glutGameModeWindow) return; }
#define GLUT_WIND_IS_RGB(x) (((x) & GLUT_INDEX) == 0)
#define GLUT_WIND_IS_INDEX(x) (((x) & GLUT_INDEX) != 0)
#define GLUT_WIND_IS_SINGLE(x) (((x) & GLUT_DOUBLE) == 0)
#define GLUT_WIND_IS_DOUBLE(x) (((x) & GLUT_DOUBLE) != 0)
#define GLUT_WIND_HAS_ACCUM(x) (((x) & GLUT_ACCUM) != 0)
#define GLUT_WIND_HAS_ALPHA(x) (((x) & GLUT_ALPHA) != 0)
#define GLUT_WIND_HAS_DEPTH(x) (((x) & GLUT_DEPTH) != 0)
#define GLUT_WIND_HAS_STENCIL(x) (((x) & GLUT_STENCIL) != 0)
#define GLUT_WIND_IS_MULTISAMPLE(x) (((x) & GLUT_MULTISAMPLE) != 0)
#define GLUT_WIND_IS_STEREO(x) (((x) & GLUT_STEREO) != 0)
#define GLUT_WIND_IS_LUMINANCE(x) (((x) & GLUT_LUMINANCE) != 0)
#define GLUT_MAP_WORK (1 << 0)
#define GLUT_EVENT_MASK_WORK (1 << 1)
#define GLUT_REDISPLAY_WORK (1 << 2)
#define GLUT_CONFIGURE_WORK (1 << 3)
#define GLUT_COLORMAP_WORK (1 << 4)
#define GLUT_DEVICE_MASK_WORK (1 << 5)
#define GLUT_FINISH_WORK (1 << 6)
#define GLUT_DEBUG_WORK (1 << 7)
#define GLUT_DUMMY_WORK (1 << 8)
#define GLUT_FULL_SCREEN_WORK (1 << 9)
#define GLUT_OVERLAY_REDISPLAY_WORK (1 << 10)
#define GLUT_REPAIR_WORK (1 << 11)
#define GLUT_OVERLAY_REPAIR_WORK (1 << 12)
/* Frame buffer capability macros and types. */
#define RGBA 0
#define BUFFER_SIZE 1
#define DOUBLEBUFFER 2
#define STEREO 3
#define AUX_BUFFERS 4
#define RED_SIZE 5 /* Used as mask bit for
"color selected". */
#define GREEN_SIZE 6
#define BLUE_SIZE 7
#define ALPHA_SIZE 8
#define DEPTH_SIZE 9
#define STENCIL_SIZE 10
#define ACCUM_RED_SIZE 11 /* Used as mask bit for
"acc selected". */
#define ACCUM_GREEN_SIZE 12
#define ACCUM_BLUE_SIZE 13
#define ACCUM_ALPHA_SIZE 14
#define LEVEL 15
#define NUM_GLXCAPS (LEVEL + 1)
#define XVISUAL (NUM_GLXCAPS + 0)
#define TRANSPARENT (NUM_GLXCAPS + 1)
#define SAMPLES (NUM_GLXCAPS + 2)
#define XSTATICGRAY (NUM_GLXCAPS + 3) /* Used as
mask bit
for "any
visual type
selected". */
#define XGRAYSCALE (NUM_GLXCAPS + 4)
#define XSTATICCOLOR (NUM_GLXCAPS + 5)
#define XPSEUDOCOLOR (NUM_GLXCAPS + 6)
#define XTRUECOLOR (NUM_GLXCAPS + 7)
#define XDIRECTCOLOR (NUM_GLXCAPS + 8)
#define SLOW (NUM_GLXCAPS + 9)
#define CONFORMANT (NUM_GLXCAPS + 10)
#define NUM_CAPS (NUM_GLXCAPS + 11)
/* Frame buffer capablities that don't have a corresponding
FrameBufferMode entry. These get used as mask bits. */
#define NUM (NUM_CAPS + 0)
#define RGBA_MODE (NUM_CAPS + 1)
#define CI_MODE (NUM_CAPS + 2)
#define LUMINANCE_MODE (NUM_CAPS + 3)
#define NONE 0
#define EQ 1
#define NEQ 2
#define LTE 3
#define GTE 4
#define GT 5
#define LT 6
#define MIN 7
typedef struct _Criterion {
int capability;
int comparison;
int value;
} Criterion;
typedef struct _FrameBufferMode {
XVisualInfo *vi;
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
/* fbc is non-NULL when the XVisualInfo* is not OpenGL-capable
(ie, GLX_USE_GL is false), but the SGIX_fbconfig extension shows
the visual's fbconfig is OpenGL-capable. The reason for this is typically
an RGBA luminance fbconfig such as 16-bit StaticGray that could
not be advertised as a GLX visual since StaticGray visuals are
required (by the GLX specification) to be color index. The
SGIX_fbconfig allows StaticGray visuals to instead advertised as
fbconfigs that can provide RGBA luminance support. */
GLXFBConfigSGIX fbc;
#endif
int valid;
int cap[NUM_CAPS];
} FrameBufferMode;
/* DisplayMode capability macros for game mode. */
#define DM_WIDTH 0 /* "width" */
#define DM_HEIGHT 1 /* "height" */
#define DM_PIXEL_DEPTH 2 /* "bpp" (bits per pixel) */
#define DM_HERTZ 3 /* "hertz" */
#define DM_NUM 4 /* "num" */
#define NUM_DM_CAPS (DM_NUM+1)
typedef struct _DisplayMode {
#ifdef _WIN32
DEVMODE devmode;
#else
/* XXX The X Window System does not have a standard
mechanism for display setting changes. On SGI
systems, GLUT could use the XSGIvc (SGI X video
control extension). Perhaps this can be done in
a future release of GLUT. */
#endif
int valid;
int cap[NUM_DM_CAPS];
} DisplayMode;
/* GLUT function types */
typedef void (GLUTCALLBACK *GLUTdisplayCB) (void);
typedef void (GLUTCALLBACK *GLUTreshapeCB) (int, int);
typedef void (GLUTCALLBACK *GLUTkeyboardCB) (unsigned char, int, int);
typedef void (GLUTCALLBACK *GLUTmouseCB) (int, int, int, int);
typedef void (GLUTCALLBACK *GLUTmotionCB) (int, int);
typedef void (GLUTCALLBACK *GLUTpassiveCB) (int, int);
typedef void (GLUTCALLBACK *GLUTentryCB) (int);
typedef void (GLUTCALLBACK *GLUTvisibilityCB) (int);
typedef void (GLUTCALLBACK *GLUTwindowStatusCB) (int);
typedef void (GLUTCALLBACK *GLUTidleCB) (void);
typedef void (GLUTCALLBACK *GLUTtimerCB) (int);
typedef void (GLUTCALLBACK *GLUTmenuStateCB) (int); /* DEPRICATED. */
typedef void (GLUTCALLBACK *GLUTmenuStatusCB) (int, int, int);
typedef void (GLUTCALLBACK *GLUTselectCB) (int);
typedef void (GLUTCALLBACK *GLUTspecialCB) (int, int, int);
typedef void (GLUTCALLBACK *GLUTspaceMotionCB) (int, int, int);
typedef void (GLUTCALLBACK *GLUTspaceRotateCB) (int, int, int);
typedef void (GLUTCALLBACK *GLUTspaceButtonCB) (int, int);
typedef void (GLUTCALLBACK *GLUTdialsCB) (int, int);
typedef void (GLUTCALLBACK *GLUTbuttonBoxCB) (int, int);
typedef void (GLUTCALLBACK *GLUTtabletMotionCB) (int, int);
typedef void (GLUTCALLBACK *GLUTtabletButtonCB) (int, int, int, int);
typedef void (GLUTCALLBACK *GLUTjoystickCB) (unsigned int buttonMask, int x, int y, int z);
typedef struct _GLUTcolorcell GLUTcolorcell;
struct _GLUTcolorcell {
/* GLUT_RED, GLUT_GREEN, GLUT_BLUE */
GLfloat component[3];
};
typedef struct _GLUTcolormap GLUTcolormap;
struct _GLUTcolormap {
Visual *visual; /* visual of the colormap */
Colormap cmap; /* X colormap ID */
int refcnt; /* number of windows using colormap */
int size; /* number of cells in colormap */
int transparent; /* transparent pixel, or -1 if opaque */
GLUTcolorcell *cells; /* array of cells */
GLUTcolormap *next; /* next colormap in list */
};
typedef struct _GLUTwindow GLUTwindow;
typedef struct _GLUToverlay GLUToverlay;
struct _GLUTwindow {
int num; /* Small integer window id (0-based). */
/* Window system related state. */
#if defined(_WIN32)
int pf; /* Pixel format. */
HDC hdc; /* Window's Win32 device context. */
#endif
Window win; /* X window for GLUT window */
GLXContext ctx; /* OpenGL context GLUT glut window */
XVisualInfo *vis; /* visual for window */
Bool visAlloced; /* if vis needs deallocate on destroy */
Colormap cmap; /* RGB colormap for window; None if CI */
GLUTcolormap *colormap; /* colormap; NULL if RGBA */
GLUToverlay *overlay; /* overlay; NULL if no overlay */
#if defined(_WIN32)
HDC renderDc; /* Win32's device context for rendering. */
#endif
Window renderWin; /* X window for rendering (might be
overlay) */
GLXContext renderCtx; /* OpenGL context for rendering (might
be overlay) */
/* GLUT settable or visible window state. */
int width; /* window width in pixels */
int height; /* window height in pixels */
int cursor; /* cursor name */
int visState; /* visibility state (-1 is unknown) */
int shownState; /* if window mapped */
int entryState; /* entry state (-1 is unknown) */
#define GLUT_MAX_MENUS 3
int menu[GLUT_MAX_MENUS]; /* attatched menu nums */
/* Window relationship state. */
GLUTwindow *parent; /* parent window */
GLUTwindow *children; /* list of children */
GLUTwindow *siblings; /* list of siblings */
/* Misc. non-API visible (hidden) state. */
Bool treatAsSingle; /* treat this window as single-buffered
(it might be "fake" though) */
Bool forceReshape; /* force reshape before display */
#if !defined(_WIN32)
Bool isDirect; /* if direct context (X11 only) */
#endif
Bool usedSwapBuffers; /* if swap buffers used last display */
long eventMask; /* mask of X events selected for */
int buttonUses; /* number of button uses, ref cnt */
int tabletPos[2]; /* tablet position (-1 is invalid) */
/* Work list related state. */
unsigned int workMask; /* mask of window work to be done */
GLUTwindow *prevWorkWin; /* link list of windows to work on */
Bool desiredMapState; /* how to mapped window if on map work
list */
Bool ignoreKeyRepeat; /* if window ignores autorepeat */
int desiredConfMask; /* mask of desired window configuration
*/
int desiredX; /* desired X location */
int desiredY; /* desired Y location */
int desiredWidth; /* desired window width */
int desiredHeight; /* desired window height */
int desiredStack; /* desired window stack */
/* Per-window callbacks. */
GLUTdisplayCB display; /* redraw */
GLUTreshapeCB reshape; /* resize (width,height) */
GLUTmouseCB mouse; /* mouse (button,state,x,y) */
GLUTmotionCB motion; /* motion (x,y) */
GLUTpassiveCB passive; /* passive motion (x,y) */
GLUTentryCB entry; /* window entry/exit (state) */
GLUTkeyboardCB keyboard; /* keyboard (ASCII,x,y) */
GLUTkeyboardCB keyboardUp; /* keyboard up (ASCII,x,y) */
GLUTwindowStatusCB windowStatus; /* window status */
GLUTvisibilityCB visibility; /* visibility */
GLUTspecialCB special; /* special key */
GLUTspecialCB specialUp; /* special up key */
GLUTbuttonBoxCB buttonBox; /* button box */
GLUTdialsCB dials; /* dials */
GLUTspaceMotionCB spaceMotion; /* Spaceball motion */
GLUTspaceRotateCB spaceRotate; /* Spaceball rotate */
GLUTspaceButtonCB spaceButton; /* Spaceball button */
GLUTtabletMotionCB tabletMotion; /* tablet motion */
GLUTtabletButtonCB tabletButton; /* tablet button */
#ifdef _WIN32
GLUTjoystickCB joystick; /* joystick */
int joyPollInterval; /* joystick polling interval */
#endif
#ifdef SUPPORT_FORTRAN
GLUTdisplayFCB fdisplay; /* Fortran display */
GLUTreshapeFCB freshape; /* Fortran reshape */
GLUTmouseFCB fmouse; /* Fortran mouse */
GLUTmotionFCB fmotion; /* Fortran motion */
GLUTpassiveFCB fpassive; /* Fortran passive */
GLUTentryFCB fentry; /* Fortran entry */
GLUTkeyboardFCB fkeyboard; /* Fortran keyboard */
GLUTkeyboardFCB fkeyboardUp; /* Fortran keyboard up */
GLUTwindowStatusFCB fwindowStatus; /* Fortran window status */
GLUTvisibilityFCB fvisibility; /* Fortran visibility */
GLUTspecialFCB fspecial; /* special key */
GLUTspecialFCB fspecialUp; /* special key up */
GLUTbuttonBoxFCB fbuttonBox; /* button box */
GLUTdialsFCB fdials; /* dials */
GLUTspaceMotionFCB fspaceMotion; /* Spaceball motion */
GLUTspaceRotateFCB fspaceRotate; /* Spaceball rotate */
GLUTspaceButtonFCB fspaceButton; /* Spaceball button */
GLUTtabletMotionFCB ftabletMotion; /* tablet motion */
GLUTtabletButtonFCB ftabletButton; /* tablet button */
#ifdef _WIN32
GLUTjoystickFCB fjoystick; /* joystick */
#endif
#endif
};
struct _GLUToverlay {
#if defined(_WIN32)
int pf;
HDC hdc;
#endif
Window win;
GLXContext ctx;
XVisualInfo *vis; /* visual for window */
Bool visAlloced; /* if vis needs deallocate on destroy */
Colormap cmap; /* RGB colormap for window; None if CI */
GLUTcolormap *colormap; /* colormap; NULL if RGBA */
int shownState; /* if overlay window mapped */
Bool treatAsSingle; /* treat as single-buffered */
#if !defined(_WIN32)
Bool isDirect; /* if direct context */
#endif
int transparentPixel; /* transparent pixel value */
GLUTdisplayCB display; /* redraw */
#ifdef SUPPORT_FORTRAN
GLUTdisplayFCB fdisplay; /* redraw */
#endif
};
typedef struct _GLUTstale GLUTstale;
struct _GLUTstale {
GLUTwindow *window;
Window win;
GLUTstale *next;
};
extern GLUTstale *__glutStaleWindowList;
#define GLUT_OVERLAY_EVENT_FILTER_MASK \
(ExposureMask | \
StructureNotifyMask | \
EnterWindowMask | \
LeaveWindowMask)
#define GLUT_DONT_PROPAGATE_FILTER_MASK \
(ButtonReleaseMask | \
ButtonPressMask | \
KeyPressMask | \
KeyReleaseMask | \
PointerMotionMask | \
Button1MotionMask | \
Button2MotionMask | \
Button3MotionMask)
#define GLUT_HACK_STOP_PROPAGATE_MASK \
(KeyPressMask | \
KeyReleaseMask)
typedef struct _GLUTmenu GLUTmenu;
typedef struct _GLUTmenuItem GLUTmenuItem;
struct _GLUTmenu {
int id; /* small integer menu id (0-based) */
Window win; /* X window for the menu */
GLUTselectCB select; /* function of menu */
GLUTmenuItem *list; /* list of menu entries */
int num; /* number of entries */
#if !defined(_WIN32)
Bool managed; /* are the InputOnly windows size
validated? */
Bool searched; /* help detect menu loops */
int pixheight; /* height of menu in pixels */
int pixwidth; /* width of menu in pixels */
#endif
int submenus; /* number of submenu entries */
GLUTmenuItem *highlighted; /* pointer to highlighted menu
entry, NULL not highlighted */
GLUTmenu *cascade; /* currently cascading this menu */
GLUTmenuItem *anchor; /* currently anchored to this entry */
int x; /* current x origin relative to the
root window */
int y; /* current y origin relative to the
root window */
#ifdef SUPPORT_FORTRAN
GLUTselectFCB fselect; /* function of menu */
#endif
};
struct _GLUTmenuItem {
Window win; /* InputOnly X window for entry */
GLUTmenu *menu; /* menu entry belongs to */
Bool isTrigger; /* is a submenu trigger? */
int value; /* value to return for selecting this
entry; doubles as submenu id
(0-base) if submenu trigger */
#if defined(_WIN32)
UINT unique; /* unique menu item id (Win32 only) */
#endif
char *label; /* __glutStrdup'ed label string */
int len; /* length of label string */
int pixwidth; /* width of X window in pixels */
GLUTmenuItem *next; /* next menu entry on list for menu */
};
typedef struct _GLUTtimer GLUTtimer;
struct _GLUTtimer {
GLUTtimer *next; /* list of timers */
#ifdef OLD_VMS
struct timeval6 timeout; /* time to be called */
#else
struct timeval timeout; /* time to be called */
#endif
GLUTtimerCB func; /* timer (value) */
int value; /* return value */
#ifdef SUPPORT_FORTRAN
GLUTtimerFCB ffunc; /* Fortran timer */
#endif
};
typedef struct _GLUTeventParser GLUTeventParser;
struct _GLUTeventParser {
int (*func) (XEvent *);
GLUTeventParser *next;
};
/* Declarations to implement glutFullScreen support with
mwm/4Dwm. */
/* The following X property format is defined in Motif 1.1's
Xm/MwmUtils.h, but GLUT should not depend on that header
file. Note: Motif 1.2 expanded this structure with
uninteresting fields (to GLUT) so just stick with the
smaller Motif 1.1 structure. */
typedef struct {
#define MWM_HINTS_DECORATIONS 2
long flags;
long functions;
long decorations;
long input_mode;
} MotifWmHints;
/* Make current and buffer swap macros. */
#ifdef _WIN32
#define MAKE_CURRENT_LAYER(window) \
{ \
HGLRC currentContext = wglGetCurrentContext(); \
HDC currentDc = wglGetCurrentDC(); \
\
if (currentContext != window->renderCtx \
|| currentDc != window->renderDc) { \
wglMakeCurrent(window->renderDc, window->renderCtx); \
} \
}
#define MAKE_CURRENT_WINDOW(window) \
{ \
HGLRC currentContext = wglGetCurrentContext(); \
HDC currentDc = wglGetCurrentDC(); \
\
if (currentContext != window->ctx || currentDc != window->hdc) { \
wglMakeCurrent(window->hdc, window->ctx); \
} \
}
#define MAKE_CURRENT_OVERLAY(overlay) \
wglMakeCurrent(overlay->hdc, overlay->ctx)
#define UNMAKE_CURRENT() \
wglMakeCurrent(NULL, NULL)
#define SWAP_BUFFERS_WINDOW(window) \
SwapBuffers(window->hdc)
#define SWAP_BUFFERS_LAYER(window) \
SwapBuffers(window->renderDc)
#else
#define MAKE_CURRENT_LAYER(window) \
glXMakeCurrent(__glutDisplay, window->renderWin, window->renderCtx)
#define MAKE_CURRENT_WINDOW(window) \
glXMakeCurrent(__glutDisplay, window->win, window->ctx)
#define MAKE_CURRENT_OVERLAY(overlay) \
glXMakeCurrent(__glutDisplay, overlay->win, overlay->ctx)
#define UNMAKE_CURRENT() \
glXMakeCurrent(__glutDisplay, None, NULL)
#define SWAP_BUFFERS_WINDOW(window) \
glXSwapBuffers(__glutDisplay, window->win)
#define SWAP_BUFFERS_LAYER(window) \
glXSwapBuffers(__glutDisplay, window->renderWin)
#endif
/* private variables from glut_event.c */
extern GLUTwindow *__glutWindowWorkList;
extern int __glutWindowDamaged;
#ifdef SUPPORT_FORTRAN
extern GLUTtimer *__glutTimerList;
extern GLUTtimer *__glutNewTimer;
#endif
extern GLUTmenu *__glutMappedMenu;
extern void (*__glutUpdateInputDeviceMaskFunc) (GLUTwindow *);
#if !defined(_WIN32)
extern void (*__glutMenuItemEnterOrLeave)(GLUTmenuItem * item,
int num, int type);
extern void (*__glutFinishMenu)(Window win, int x, int y);
extern void (*__glutPaintMenu)(GLUTmenu * menu);
extern void (*__glutStartMenu)(GLUTmenu * menu,
GLUTwindow * window, int x, int y, int x_win, int y_win);
extern GLUTmenu * (*__glutGetMenuByNum)(int menunum);
extern GLUTmenuItem * (*__glutGetMenuItem)(GLUTmenu * menu,
Window win, int *which);
extern GLUTmenu * (*__glutGetMenu)(Window win);
#endif
/* private variables from glut_init.c */
extern Atom __glutWMDeleteWindow;
extern Display *__glutDisplay;
extern unsigned int __glutDisplayMode;
extern char *__glutDisplayString;
extern XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle,
Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc);
extern GLboolean __glutDebug;
extern GLboolean __glutForceDirect;
extern GLboolean __glutIconic;
extern GLboolean __glutTryDirect;
extern Window __glutRoot;
extern XSizeHints __glutSizeHints;
extern char **__glutArgv;
extern char *__glutProgramName;
extern int __glutArgc;
extern int __glutConnectionFD;
extern int __glutInitHeight;
extern int __glutInitWidth;
extern int __glutInitX;
extern int __glutInitY;
extern int __glutScreen;
extern int __glutScreenHeight;
extern int __glutScreenWidth;
extern Atom __glutMotifHints;
extern unsigned int __glutModifierMask;
#ifdef _WIN32
extern void (__cdecl *__glutExitFunc)(int retval);
#endif
extern char *__glutPPMFile;
/* private variables from glut_menu.c */
extern GLUTmenuItem *__glutItemSelected;
extern GLUTmenu **__glutMenuList;
extern void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);
extern void __glutMenuModificationError(void);
extern void __glutSetMenuItem(GLUTmenuItem * item,
const char *label, int value, Bool isTrigger);
/* private variables from glut_win.c */
extern GLUTwindow **__glutWindowList;
extern GLUTwindow *__glutCurrentWindow;
extern GLUTwindow *__glutMenuWindow;
extern GLUTmenu *__glutCurrentMenu;
extern int __glutWindowListSize;
extern void (*__glutFreeOverlayFunc) (GLUToverlay *);
extern void __glutFreeOverlay(GLUToverlay * overlay);
extern XVisualInfo *__glutDetermineWindowVisual(Bool * treatAsSingle,
Bool * visAlloced, void **fbc);
/* private variables from glut_ppm.c */
extern void __glutWritePPMFile(void);
/* private variables from glut_mesa.c */
extern int __glutMesaSwapHackSupport;
/* private variables from glut_gamemode.c */
extern GLUTwindow *__glutGameModeWindow;
/* private routines from glut_cindex.c */
extern GLUTcolormap * __glutAssociateNewColormap(XVisualInfo * vis);
extern void __glutFreeColormap(GLUTcolormap *);
/* private routines from glut_cmap.c */
extern void __glutSetupColormap(
XVisualInfo * vi,
GLUTcolormap ** colormap,
Colormap * cmap);
#if !defined(_WIN32)
extern void __glutEstablishColormapsProperty(
GLUTwindow * window);
extern GLUTwindow *__glutToplevelOf(GLUTwindow * window);
#endif
/* private routines from glut_cursor.c */
extern void __glutSetCursor(GLUTwindow *window);
/* private routines from glut_event.c */
extern void __glutPutOnWorkList(GLUTwindow * window,
int work_mask);
extern void __glutRegisterEventParser(GLUTeventParser * parser);
extern void __glutPostRedisplay(GLUTwindow * window, int layerMask);
extern void handleTimeouts(void);
/* private routines from glut_init.c */
#if !defined(_WIN32)
extern void __glutOpenXConnection(char *display);
#else
extern void __glutOpenWin32Connection(char *display);
#endif
#ifdef OLD_VMS
extern void __glutInitTime(struct timeval6 *beginning);
#else
extern void __glutInitTime(struct timeval *beginning);
#endif
/* private routines for glut_menu.c (or win32_menu.c) */
#if defined(_WIN32)
extern GLUTmenu *__glutGetMenu(Window win);
extern GLUTmenu *__glutGetMenuByNum(int menunum);
extern GLUTmenuItem *__glutGetMenuItem(GLUTmenu * menu,
Window win, int *which);
extern void __glutStartMenu(GLUTmenu * menu,
GLUTwindow * window, int x, int y, int x_win, int y_win);
extern void __glutFinishMenu(Window win, int x, int y);
#endif
extern void __glutSetMenu(GLUTmenu * menu);
/* private routines from glut_util.c */
extern char * __glutStrdup(const char *string);
extern void __glutWarning(char *format,...);
extern void __glutFatalError(char *format,...);
extern void __glutFatalUsage(char *format,...);
/* private routines from glut_win.c */
extern GLUTwindow *__glutGetWindow(Window win);
extern void __glutChangeWindowEventMask(long mask, Bool add);
extern XVisualInfo *__glutDetermineVisual(
unsigned int mode,
Bool * fakeSingle,
XVisualInfo * (getVisualInfo) (unsigned int));
extern XVisualInfo *__glutGetVisualInfo(unsigned int mode);
extern void __glutSetWindow(GLUTwindow * window);
extern void __glutReshapeFunc(GLUTreshapeCB reshapeFunc,
int callingConvention);
extern void GLUTCALLBACK __glutDefaultReshape(int, int);
extern GLUTwindow *__glutCreateWindow(
GLUTwindow * parent,
int x, int y, int width, int height, int gamemode);
extern void __glutDestroyWindow(
GLUTwindow * window,
GLUTwindow * initialWindow);
#if !defined(_WIN32)
/* private routines from glut_glxext.c */
extern int __glutIsSupportedByGLX(char *);
extern int __glut_glXBindChannelToWindowSGIX(Display *dpy, int screen,
int channel, Window window);
extern int __glut_glXChannelRectSGIX(Display *dpy, int screen, int channel,
int x, int y, int w, int h);
extern int __glut_glXQueryChannelRectSGIX(Display *dpy, int screen,
int channel, int *x, int *y,
int *w, int *h);
extern int __glut_glXQueryChannelDeltasSGIX(Display *dpy, int screen,
int channel, int *dx, int *dy,
int *dw, int *dh);
extern int __glut_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel,
GLenum synctype);
extern GLXContext __glut_glXCreateContextWithConfigSGIX(Display *dpy,
GLXFBConfigSGIX config,
int render_type,
GLXContext share_list,
Bool direct);
extern int __glut_glXGetFBConfigAttribSGIX(Display *dpy,
GLXFBConfigSGIX config,
int attribute,
int *value);
extern GLXFBConfigSGIX __glut_glXGetFBConfigFromVisualSGIX(Display *dpy,
XVisualInfo *vis);
#endif
/* private routines from glut_input.c */
extern void __glutUpdateInputDeviceMask(GLUTwindow * window);
/* private routines from glut_mesa.c */
extern void __glutDetermineMesaSwapHackSupport(void);
/* private routines from glut_gameglut.c */
extern void __glutCloseDownGameMode(void);
/* private variables from glut_swap.c (BrianP) */
extern GLint __glutFPS;
extern GLint __glutSwapCount;
extern GLint __glutSwapTime;
#if defined(_WIN32)
/* private routines from win32_*.c */
extern LONG WINAPI __glutWindowProc(HWND win, UINT msg, WPARAM w, LPARAM l);
extern HDC XHDC;
#endif
#endif /* __glutint_h__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
/*
* Demo of off-screen Mesa rendering
*
* See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
*
* If you want to render BIG images you'll probably have to increase
* MAX_WIDTH and MAX_Height in src/config.h.
*
* This program is in the public domain.
*
* Brian Paul
*
* PPM output provided by Joerg Schmalzl.
* ASCII PPM output added by Brian Paul.
*
* Usage: osdemo [filename]
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define GL_GLEXT_PROTOTYPES
#include "GL/osmesa.h"
#include <GL/glext.h>
#include "GL/glu.h"
#include "shaderutil.h"
#include <kos32sys.h>
int _CRT_MT=0;
static int Width = 500;
static int Height = 400;
int check_events();
GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
GLfloat angle = 0.0;
GLboolean animate = GL_TRUE; /* Animation */
GLfloat eyesep = 5.0; /* Eye separation. */
GLfloat fix_point = 40.0; /* Fixation point distance. */
GLfloat left, right, asp; /* Stereo frustum params. */
void Init( void );
void Reshape( int width, int height );
void Draw( void );
void Idle();
void Key(unsigned char key, int x, int y);
inline void Blit(void *bitmap, int dst_x, int dst_y,
int src_x, int src_y, int w, int h,
int src_w, int src_h, int stride)
{
volatile struct blit_call bc;
bc.dstx = dst_x;
bc.dsty = dst_y;
bc.w = w;
bc.h = h;
bc.srcx = src_x;
bc.srcy = src_y;
bc.srcw = src_w;
bc.srch = src_h;
bc.stride = stride;
bc.bitmap = bitmap;
__asm__ __volatile__(
"int $0x40"
::"a"(73),"b"(0),"c"(&bc.dstx));
};
static inline uint32_t wait_os_event(int time)
{
uint32_t val;
__asm__ __volatile__(
"int $0x40"
:"=a"(val)
:"a"(23),"b"(time));
return val;
};
int main(int argc, char *argv[])
{
OSMesaContext ctx;
void *buffer;
char *filename = NULL;
int ev;
int repeat=1;
/* Create an RGBA-mode context */
/* specify Z, stencil, accum sizes */
ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL );
if (!ctx) {
printf("OSMesaCreateContext failed!\n");
return 0;
}
/* Allocate the image buffer */
buffer = malloc( Width * Height * 4 * sizeof(GLubyte) );
if (!buffer) {
printf("Alloc image buffer failed!\n");
return 0;
}
// __asm__ __volatile__("int3");
/* Bind the buffer to the context and make it current */
if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) {
printf("OSMesaMakeCurrent failed!\n");
return 0;
}
{
int z, s, a;
glGetIntegerv(GL_DEPTH_BITS, &z);
glGetIntegerv(GL_STENCIL_BITS, &s);
glGetIntegerv(GL_ACCUM_RED_BITS, &a);
printf("Depth=%d Stencil=%d Accum=%d\n", z, s, a);
}
Reshape(Width, Height);
Init();
Draw();
printf("all done\n");
DrawWindow(10, 10, Width+9, Height+26, "OpenGL Engine Demo", 0x000000, 0x74);
Blit(buffer, 5, 22, 0, 0, Width, Height, Width,Height,Width*4);
while(repeat)
{
oskey_t key;
ev = wait_os_event(1);
switch(ev)
{
case 1:
DrawWindow(10, 10, Width+9, Width+26, NULL, 0x000000,0x74);
Blit(buffer, 5, 22, 0, 0, Width, Height, Width,Height,Width*4);
continue;
case 2:
key = get_key();
Key(key.code, 0, 0);
Draw();
Blit(buffer, 5, 22, 0, 0, Width, Height, Width,Height,Width*4);
continue;
case 3:
if(get_os_button()==1)
repeat=0;
continue;
};
Idle();
Draw();
Blit(buffer, 5, 22, 0, 0, Width, Height, Width,Height,Width*4);
};
/* free the image buffer */
free( buffer );
/* destroy the context */
OSMesaDestroyContext( ctx );
return 0;
}
int atexit(void (*func)(void))
{
return 0;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,494 @@
/* readtex.c */
/*
* Read an SGI .rgb image file and generate a mipmap texture set.
* Much of this code was borrowed from SGI's tk OpenGL toolkit.
*/
#include <GL/gl.h>
#include <GL/glu.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "readtex.h"
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
/*
** RGB Image Structure
*/
typedef struct _TK_RGBImageRec {
GLint sizeX, sizeY;
GLint components;
unsigned char *data;
} TK_RGBImageRec;
/******************************************************************************/
typedef struct _rawImageRec {
unsigned short imagic;
unsigned short type;
unsigned short dim;
unsigned short sizeX, sizeY, sizeZ;
unsigned long min, max;
unsigned long wasteBytes;
char name[80];
unsigned long colorMap;
FILE *file;
unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
unsigned long rleEnd;
GLuint *rowStart;
GLint *rowSize;
} rawImageRec;
/******************************************************************************/
static void ConvertShort(unsigned short *array, long length)
{
unsigned long b1, b2;
unsigned char *ptr;
ptr = (unsigned char *)array;
while (length--) {
b1 = *ptr++;
b2 = *ptr++;
*array++ = (unsigned short) ((b1 << 8) | (b2));
}
}
static void ConvertLong(GLuint *array, long length)
{
unsigned long b1, b2, b3, b4;
unsigned char *ptr;
ptr = (unsigned char *)array;
while (length--) {
b1 = *ptr++;
b2 = *ptr++;
b3 = *ptr++;
b4 = *ptr++;
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
}
}
static rawImageRec *RawImageOpen(const char *fileName)
{
union {
int testWord;
char testByte[4];
} endianTest;
rawImageRec *raw;
GLenum swapFlag;
int x;
size_t result;
endianTest.testWord = 1;
if (endianTest.testByte[0] == 1) {
swapFlag = GL_TRUE;
} else {
swapFlag = GL_FALSE;
}
raw = (rawImageRec *)calloc(1, sizeof(rawImageRec));
if (raw == NULL) {
fprintf(stderr, "Out of memory!\n");
return NULL;
}
raw->file = fopen(fileName, "rb");
if (raw->file == NULL) {
const char *baseName = strrchr(fileName, '/');
if(baseName)
raw->file = fopen(baseName + 1, "rb");
if(raw->file == NULL) {
free(raw);
return NULL;
}
}
result = fread(raw, 1, 12, raw->file);
assert(result == 12);
if (swapFlag) {
ConvertShort(&raw->imagic, 1);
ConvertShort(&raw->type, 1);
ConvertShort(&raw->dim, 1);
ConvertShort(&raw->sizeX, 1);
ConvertShort(&raw->sizeY, 1);
ConvertShort(&raw->sizeZ, 1);
}
raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
if (raw->sizeZ==4) {
raw->tmpA = (unsigned char *)malloc(raw->sizeX*256);
}
if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
raw->tmpB == NULL) {
fprintf(stderr, "Out of memory!\n");
free(raw->tmp);
free(raw->tmpR);
free(raw->tmpG);
free(raw->tmpB);
free(raw->tmpA);
free(raw);
return NULL;
}
if ((raw->type & 0xFF00) == 0x0100) {
x = raw->sizeY * raw->sizeZ * sizeof(GLuint);
raw->rowStart = (GLuint *)malloc(x);
raw->rowSize = (GLint *)malloc(x);
if (raw->rowStart == NULL || raw->rowSize == NULL) {
fprintf(stderr, "Out of memory!\n");
free(raw->tmp);
free(raw->tmpR);
free(raw->tmpG);
free(raw->tmpB);
free(raw->tmpA);
free(raw->rowStart);
free(raw->rowSize);
free(raw);
return NULL;
}
raw->rleEnd = 512 + (2 * x);
fseek(raw->file, 512, SEEK_SET);
result = fread(raw->rowStart, 1, x, raw->file);
assert(result == x);
result = fread(raw->rowSize, 1, x, raw->file);
assert(result == x);
if (swapFlag) {
ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
}
}
return raw;
}
static void RawImageClose(rawImageRec *raw)
{
fclose(raw->file);
free(raw->tmp);
free(raw->tmpR);
free(raw->tmpG);
free(raw->tmpB);
if (raw->rowStart)
free(raw->rowStart);
if (raw->rowSize)
free(raw->rowSize);
if (raw->sizeZ>3) {
free(raw->tmpA);
}
free(raw);
}
static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z)
{
unsigned char *iPtr, *oPtr, pixel;
int count, done = 0;
size_t result;
if ((raw->type & 0xFF00) == 0x0100) {
fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
result = fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
raw->file);
assert(result == (unsigned int)raw->rowSize[y+z*raw->sizeY]);
iPtr = raw->tmp;
oPtr = buf;
while (!done) {
pixel = *iPtr++;
count = (int)(pixel & 0x7F);
if (!count) {
done = 1;
return;
}
if (pixel & 0x80) {
while (count--) {
*oPtr++ = *iPtr++;
}
} else {
pixel = *iPtr++;
while (count--) {
*oPtr++ = pixel;
}
}
}
} else {
fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
SEEK_SET);
result = fread(buf, 1, raw->sizeX, raw->file);
assert(result == raw->sizeX);
}
}
static void RawImageGetData(rawImageRec *raw, TK_RGBImageRec *final)
{
unsigned char *ptr;
int i, j;
final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
if (final->data == NULL) {
fprintf(stderr, "Out of memory!\n");
return;
}
ptr = final->data;
for (i = 0; i < (int)(raw->sizeY); i++) {
RawImageGetRow(raw, raw->tmpR, i, 0);
RawImageGetRow(raw, raw->tmpG, i, 1);
RawImageGetRow(raw, raw->tmpB, i, 2);
if (raw->sizeZ>3) {
RawImageGetRow(raw, raw->tmpA, i, 3);
}
for (j = 0; j < (int)(raw->sizeX); j++) {
*ptr++ = *(raw->tmpR + j);
*ptr++ = *(raw->tmpG + j);
*ptr++ = *(raw->tmpB + j);
if (raw->sizeZ>3) {
*ptr++ = *(raw->tmpA + j);
}
}
}
}
static TK_RGBImageRec *tkRGBImageLoad(const char *fileName)
{
rawImageRec *raw;
TK_RGBImageRec *final;
raw = RawImageOpen(fileName);
if (!raw) {
fprintf(stderr, "File not found\n");
return NULL;
}
final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
if (final == NULL) {
fprintf(stderr, "Out of memory!\n");
RawImageClose(raw);
return NULL;
}
final->sizeX = raw->sizeX;
final->sizeY = raw->sizeY;
final->components = raw->sizeZ;
RawImageGetData(raw, final);
RawImageClose(raw);
return final;
}
static void FreeImage( TK_RGBImageRec *image )
{
free(image->data);
free(image);
}
/*
* Load an SGI .rgb file and generate a set of 2-D mipmaps from it.
* Input: imageFile - name of .rgb to read
* intFormat - internal texture format to use, or number of components
* Return: GL_TRUE if success, GL_FALSE if error.
*/
GLboolean LoadRGBMipmaps( const char *imageFile, GLint intFormat )
{
GLint w, h;
return LoadRGBMipmaps2( imageFile, GL_TEXTURE_2D, intFormat, &w, &h );
}
GLboolean LoadRGBMipmaps2( const char *imageFile, GLenum target,
GLint intFormat, GLint *width, GLint *height )
{
GLint error;
GLenum format;
TK_RGBImageRec *image;
image = tkRGBImageLoad( imageFile );
if (!image) {
return GL_FALSE;
}
if (image->components==3) {
format = GL_RGB;
}
else if (image->components==4) {
format = GL_RGBA;
}
else {
/* not implemented */
fprintf(stderr,
"Error in LoadRGBMipmaps %d-component images not implemented\n",
image->components );
FreeImage(image);
return GL_FALSE;
}
error = gluBuild2DMipmaps( target,
intFormat,
image->sizeX, image->sizeY,
format,
GL_UNSIGNED_BYTE,
image->data );
*width = image->sizeX;
*height = image->sizeY;
FreeImage(image);
return error ? GL_FALSE : GL_TRUE;
}
/*
* Load an SGI .rgb file and return a pointer to the image data.
* Input: imageFile - name of .rgb to read
* Output: width - width of image
* height - height of image
* format - format of image (GL_RGB or GL_RGBA)
* Return: pointer to image data or NULL if error
*/
GLubyte *LoadRGBImage( const char *imageFile, GLint *width, GLint *height,
GLenum *format )
{
TK_RGBImageRec *image;
GLint bytes;
GLubyte *buffer;
image = tkRGBImageLoad( imageFile );
if (!image) {
return NULL;
}
if (image->components==3) {
*format = GL_RGB;
}
else if (image->components==4) {
*format = GL_RGBA;
}
else {
/* not implemented */
fprintf(stderr,
"Error in LoadRGBImage %d-component images not implemented\n",
image->components );
FreeImage(image);
return NULL;
}
*width = image->sizeX;
*height = image->sizeY;
bytes = image->sizeX * image->sizeY * image->components;
buffer = (GLubyte *) malloc(bytes);
if (!buffer) {
FreeImage(image);
return NULL;
}
memcpy( (void *) buffer, (void *) image->data, bytes );
FreeImage(image);
return buffer;
}
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
static void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes,
const GLubyte *src,
GLushort *dest)
{
GLint i, j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
const GLfloat r = (src[0]) / 255.0;
const GLfloat g = (src[1]) / 255.0;
const GLfloat b = (src[2]) / 255.0;
GLfloat y, cr, cb;
GLint iy, icr, icb;
y = r * 65.481 + g * 128.553 + b * 24.966 + 16;
cb = r * -37.797 + g * -74.203 + b * 112.0 + 128;
cr = r * 112.0 + g * -93.786 + b * -18.214 + 128;
/*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/
iy = (GLint) CLAMP(y, 0, 254);
icb = (GLint) CLAMP(cb, 0, 254);
icr = (GLint) CLAMP(cr, 0, 254);
if (j & 1) {
/* odd */
*dest = (iy << 8) | icr;
}
else {
/* even */
*dest = (iy << 8) | icb;
}
dest++;
src += texel_bytes;
}
}
}
/*
* Load an SGI .rgb file and return a pointer to the image data, converted
* to 422 yuv.
*
* Input: imageFile - name of .rgb to read
* Output: width - width of image
* height - height of image
* Return: pointer to image data or NULL if error
*/
GLushort *LoadYUVImage( const char *imageFile, GLint *width, GLint *height )
{
TK_RGBImageRec *image;
GLushort *buffer;
image = tkRGBImageLoad( imageFile );
if (!image) {
return NULL;
}
if (image->components != 3 && image->components !=4 ) {
/* not implemented */
fprintf(stderr,
"Error in LoadYUVImage %d-component images not implemented\n",
image->components );
FreeImage(image);
return NULL;
}
*width = image->sizeX;
*height = image->sizeY;
buffer = (GLushort *) malloc( image->sizeX * image->sizeY * 2 );
if (buffer)
ConvertRGBtoYUV( image->sizeX,
image->sizeY,
image->components,
image->data,
buffer );
FreeImage(image);
return buffer;
}

View File

@@ -0,0 +1,26 @@
/* readtex.h */
#ifndef READTEX_H
#define READTEX_H
#include <GL/gl.h>
extern GLboolean
LoadRGBMipmaps( const char *imageFile, GLint intFormat );
extern GLboolean
LoadRGBMipmaps2( const char *imageFile, GLenum target,
GLint intFormat, GLint *width, GLint *height );
extern GLubyte *
LoadRGBImage( const char *imageFile,
GLint *width, GLint *height, GLenum *format );
extern GLushort *
LoadYUVImage( const char *imageFile, GLint *width, GLint *height );
#endif

Binary file not shown.

View File

@@ -0,0 +1,63 @@
#ifndef SHADER_UTIL_H
#define SHADER_UTIL_H
struct uniform_info
{
const char *name;
GLuint size; /**< number of value[] elements: 1, 2, 3 or 4 */
GLenum type; /**< GL_FLOAT, GL_FLOAT_VEC4, GL_INT, etc */
GLfloat value[4];
GLint location; /**< filled in by InitUniforms() */
};
#define END_OF_UNIFORMS { NULL, 0, GL_NONE, { 0, 0, 0, 0 }, -1 }
struct attrib_info
{
const char *name;
GLuint size; /**< number of value[] elements: 1, 2, 3 or 4 */
GLenum type; /**< GL_FLOAT, GL_FLOAT_VEC4, GL_INT, etc */
GLint location;
};
extern GLboolean
ShadersSupported(void);
extern GLuint
CompileShaderText(GLenum shaderType, const char *text);
extern GLuint
CompileShaderFile(GLenum shaderType, const char *filename);
extern GLuint
LinkShaders(GLuint vertShader, GLuint fragShader);
extern GLboolean
ValidateShaderProgram(GLuint program);
extern GLdouble
GetShaderCompileTime(void);
extern GLdouble
GetShaderLinkTime(void);
extern void
SetUniformValues(GLuint program, struct uniform_info uniforms[]);
extern GLuint
GetUniforms(GLuint program, struct uniform_info uniforms[]);
extern void
PrintUniforms(const struct uniform_info uniforms[]);
extern GLuint
GetAttribs(GLuint program, struct attrib_info attribs[]);
extern void
PrintAttribs(const struct attrib_info attribs[]);
#endif /* SHADER_UTIL_H */

View File

@@ -0,0 +1,110 @@
Josh Aas <joshmoz@gmail.com> Memory leak fix for quartz backend
Daniel Amelang <dan@amelang.net> Many (magic) floating-point optimizations
Shawn T. Amundson <amundson@gtk.org> Build fix
Olivier Andrieu <oliv__a@users.sourceforge.net> PNG backend
Peter Dennis Bartok <peter@novonyx.com> Bug fix for clipping
Dave Beckett <dajobe@debian.org> Build fixes, Debian packaging
Kai-Uwe Behrmann <ku.b@gmx.de> SVG bug fixes
Christian Biesinger <cbiesinger@web.de> BeOS backend
Billy Biggs <vektor@dumbterm.net> Pixman code merge. Optimization. Fixes for subtle rendering bugs.
Hans Breuer <hans@breuer.org> win32 bug fixes, build fixes, and improvements
Brian Cameron <brian.cameron@sun.com> Flag bug in Sun's X server
Carlos Garcia Campos <carlosgc@gnome.org> libspectre integration into the test-suite
Andrea Canciani <ranma42@gmail.com> Bugs, quartz backend improvements and type 6/7 patterns.
Damien Carbery <damien.carbery@sun.com> Build fixes
Andrew Chant <andrew.chant@utoronto.ca> Adding const where needed
Steve Chaplin <stevech1097@yahoo.com.au> Bug fixes for PNG reading
Tomasz Cholewo <cholewo@ieee-cis.org> Bug fixes
Manu Cornet <manu@manucornet.net> SVG build fix
Frederic Crozat <fcrozat@mandriva.com> Fix test suite for OPD platforms (IA64 or PPC64)
Julien Danjou <julien@danjou.info> XCB fixes
Radek Doulík <rodo@novell.com> Bug report and test case
John Ehresman <jpe@wingide.com> Build fixes for win32
John Ellson <ellson@research.att.com> First font/glyph extents functions
Michael Emmel <mike.emmel@gmail.com> DirectFB backend
Miklós Erdélyi <erdelyim@gmail.com> Fix typo leading to a crash
Behdad Esfahbod <behdad@behdad.org> Huge piles of bug fixes, improvements, and general maintenance
Larry Ewing <lewing@novell.com> Test case for group-clip
Brian Ewins <Brian.Ewins@gmail.com> ATSUI maintenance (first success at making it really work)
Bertram Felgenhauer <int-e@gmx.de> Fixes for subtle arithmetic errors
Damian Frank <damian.frank@gmail.com> Build system improvements for win32
Bdale Garbee <bdale@gag.com> Provided essential support for cairo achitecture sessions
Jens Granseuer <jensgr@gmx.net> Fixes to generate proper compiler flags
Laxmi Harikumar <laxmi.harikumar@digital.com> Build fix
J. Ali Harlow <ali@avrc.city.ac.uk> win32 backend updates
Mathias Hasselmann <mathias.hasselmann@gmx.de> Significant reduction of calls to malloc
Richard Henderson <rth@twiddle.net> "slim" macros for better shared libraries
James Henstridge <james@daa.com.au> Build fixes related to freetype
Graydon Hoare <graydon@redhat.com> Support for non-render X server, first real text support
Thomas Hunger <info@teh-web.de> Initial version of cairo_in_stroke/fill
Thomas Jaeger <ThJaeger@gmail.com> Extended repeat modes for X
Björn Lindqvist <bjourne@gmail.com> Performance test cases
Kristian Høgsberg <krh@redhat.com> PDF backend, PS backend with meta-surfaces
Amaury Jacquot <sxpert@esitcom.org> Documentation review, appplication testing
Adrian Johnson <ajohnson@redneon.com> PDF backend improvement
Michael Johnson <ahze@ahze.net> Bug fix for pre-C99 compilers
Jonathon Jongsma <jonathon.jongsma@gmail.com> Fix documentation typos
Øyvind Kolås <pippin@freedesktop.org> OpenVG backend, Bug fixes. Better default values.
Martin Kretzschmar <martink@gnome.org> Arithmetic fix for 64-bit architectures
Mathieu Lacage <Mathieu.Lacage@sophia.inria.fr> several bug/typo fixes
Dominic Lachowicz <domlachowicz@gmail.com> PDF conformance fix, fix image surface to zero out contents
Alexander Larsson <alexl@redhat.com> Profiling and performance fixes.
Tor Lillqvist <tml@novell.com> win32 build fixes, build scripts
Jinghua Luo <sunmoon1997@gmail.com> Add bitmap glyph transformation, many freetype and glitz fixes
Luke-Jr <luke-jr@utopios.org> Build fix for cross-compiling
Kjartan Maraas <kmaraas@gnome.org> Several fixes for sparse, lots of debug help for multi-thread bugs
Nis Martensen <nis.martensen@web.de> Bug fix for sub paths
Jordi Mas <jordi@ximian.com> Bug fix for cairo_show_text
Nicholas Miell <nmiell@gmail.com> Fixes for linking bugs on AMD64
Eugeniy Meshcheryakov <eugen@debian.org> PS/PDF font subsetting improvements
Zakharov Mikhail <zmey20000@yahoo.com> Build fix for HP-UX
Christopher (Monty) Montgomery <xiphmont@gmail.com> Performnace fix (subimage_copy), multi-thread testing
Tim Mooney <enchanter@users.sourceforge.net> Fix test suite to compile with Solaris compiler
Jeff Muizelaar <jeff@infidigm.net> Patient, painful, pixman code merge. Many fixes for intricacies of dashing.
Yevgen Muntyan <muntyan@tamu.edu> win32 build fix
Declan Naughton <piratepenguin@gmail.com> Fix documentation typos
Peter Nilsson <c99pnn@cs.umu.se> Glitz backend
Henning Noren <henning.noren.402@student.lu.se> Fix memory leak
Geoff Norton <gnorton@customerdna.com> Build fixes
Robert O'Callahan <rocallahan@novell.com> Const-correctness fixes, several new API functions for completeness (and to help mozilla)
Ian Osgood <iano@quirkster.com> XCB backend maintenance
Benjamin Otte <in7y118@public.uni-hamburg.de> Refinements to cairo/perf timing
Mike Owens <etc@filespanker.com> Bug fixes
Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr> SVG backend
Keith Packard <keithp@keithp.com> Original concept, polygon tessellation, dashing, font metrics rewrite
Stuart Parmenter <pavlov@pavlov.net> Original GDI+ backend, win32 fixes
Alfred Peng <alfred.peng@sun.com> Fixes for Sun compilers and for a memory leak
Christof Petig <christof@petig-baender.de> Build fixes related to freetype
Joonas Pihlaja <jpihlaja@cc.helsinki.fi> Huge improvements to the tessellator performance
Mart Raudsepp <leio@dustbite.net> Build fixes
David Reveman <davidr@novell.com> New pattern API, glitz backend
Calum Robinson <calumr@mac.com> Quartz backend
Pavel Roskin <proski@gnu.org> Several cleanups to eliminate warnings
Tim Rowley <tim.rowley@gmail.com> Quartz/ATSUI fixes, X server workarounds, win32 glyph path support, test case to expose gradient regression
Soeren Sandmann <sandmann@daimi.au.dk> Lots of MMX love for pixman compositing
Torsten Schönfeld <kaffeetisch@gmx.de> Build fixes
Jamey Sharp <jamey@minilop.net> Surface/font backend virtualization, XCB backend
Jason Dorje Short <jdorje@users.sf.net> Build fixes and bug fixes
Jeff Smith <whydoubt@yahoo.com> Fixes for intricacies of stroking code
Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix
Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc
Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option
Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend
Pierre Tardy <tardyp@gmail.com> EGL support and testing, OpenVG backend
Karl Tomlinson <karlt+@karlt.net> Optimisation and obscure bug fixes (mozilla)
Alp Toker <alp@atoker.com> Fix several code/comment typos
Malcolm Tredinnick <malcolm@commsecure.com.au> Documentation fixes
David Turner <david@freetype.org> Optimize gradient calculations
Kalle Vahlman <kalle.vahlman@gmail.com> Allow perf reports to be compared across different platforms
Sasha Vasko <sasha@aftercode.net> Build fix to compile without xlib backend
Vladimir Vukicevic <vladimir@pobox.com> Quartz backend rewrite, win32/quartz maintenance
Jonathan Watt <jwatt@jwatt.org> win32 fixes
Peter Weilbacher <pmw@avila.aip.de> OS/2 backend
Dan Williams <dcbw@redhat.com> Implemnt MMX function to help OLPC
Chris Wilson <chris@chris-wilson.co.uk> Large-scale robustness improvements, (warn_unsed_result and malloc failure injection)
Carl Worth <cworth@isi.edu> Original library, support for paths, images
Richard D. Worth <richard@theworths.org> Build fixes for cygwin
Kent Worsnop <kworsnop@accesswave.ca> Fix PDF dashing bug
Dave Yeo <daveryeo@telus.net> Build fix for win32
(please let us know if we have missed anyone)

View File

@@ -0,0 +1,109 @@
Here's an effort to document some of the academic work that was
referenced during the implementation of cairo. It is presented in the
context of operations as they would be performed by either
cairo_stroke() or cairo_fill():
Given a Bézier path, approximate it with line segments:
The deCasteljau algorithm
"Outillages methodes calcul", P de Casteljau, technical
report, - Andre Citroen Automobiles SA, Paris, 1959
That technical report might be "hard" to find, but fortunately
this algorithm will be described in any reasonable textbook on
computational geometry. Two that have been recommended by
cairo contributors are:
"Computational Geometry, Algorithms and Applications", M. de
Berg, M. van Kreveld, M. Overmars, M. Schwarzkopf;
Springer-Verlag, ISBN: 3-540-65620-0.
"Computational Geometry in C (Second Edition)", Joseph
O'Rourke, Cambridge University Press, ISBN 0521640105.
Then, if stroking, construct a polygonal representation of the pen
approximating a circle (if filling skip three steps):
"Good approximation of circles by curvature-continuous Bezier
curves", Tor Dokken and Morten Daehlen, Computer Aided
Geometric Design 8 (1990) 22-41.
Add points to that pen based on the initial/final path faces and take
the convex hull:
Convex hull algorithm
[Again, see your favorite computational geometry
textbook. Should cite the name of the algorithm cairo uses
here, if it has a name.]
Now, "convolve" the "tracing" of the pen with the tracing of the path:
"A Kinetic Framework for Computational Geometry", Leonidas
J. Guibas, Lyle Ramshaw, and Jorge Stolfi, Proceedings of the
24th IEEE Annual Symposium on Foundations of Computer Science
(FOCS), November 1983, 100-111.
The result of the convolution is a polygon that must be filled. A fill
operations begins here. We use a very conventional Bentley-Ottmann
pass for computing the intersections, informed by some hints on robust
implementation courtesy of John Hobby:
John D. Hobby, Practical Segment Intersection with Finite
Precision Output, Computation Geometry Theory and
Applications, 13(4), 1999.
http://cm.bell-labs.com/who/hobby/93_2-27.pdf
Hobby's primary contribution in that paper is his "tolerance square"
algorithm for robustness against edges being "bent" due to restricting
intersection coordinates to the grid available by finite-precision
arithmetic. This is one algorithm we have not implemented yet.
We use a data-structure called Skiplists in the our implementation
of Bentley-Ottmann:
W. Pugh, Skip Lists: a Probabilistic Alternative to Balanced Trees,
Communications of the ACM, vol. 33, no. 6, pp.668-676, 1990.
http://citeseer.ist.psu.edu/pugh90skip.html
The random number generator used in our skip list implementation is a
very small generator by Hars and Petruska. The generator is based on
an invertable function on Z_{2^32} with full period and is described
in
Hars L. and Petruska G.,
``Pseudorandom Recursions: Small and Fast Pseurodandom
Number Generators for Embedded Applications'',
Hindawi Publishing Corporation
EURASIP Journal on Embedded Systems
Volume 2007, Article ID 98417, 13 pages
doi:10.1155/2007/98417
http://www.hindawi.com/getarticle.aspx?doi=10.1155/2007/98417&e=cta
From the result of the intersection-finding pass, we are currently
computing a tessellation of trapezoids, (the exact manner is
undergoing some work right now with some important speedup), but we
may want to rasterize directly from those edges at some point.
Given the set of tessellated trapezoids, we currently execute a
straightforward, (and slow), point-sampled rasterization, (and
currently with a near-pessimal regular 15x17 grid).
We've now computed a mask which gets fed along with the source and
destination into cairo's fundamental rendering equation. The most
basic form of this equation is:
destination = (source IN mask) OP destination
with the restriction that no part of the destination outside the
current clip region is affected. In this equation, IN refers to the
Porter-Duff "in" operation, while OP refers to a any user-selected
Porter-Duff operator:
T. Porter & T. Duff, Compositing Digital Images Computer
Graphics Volume 18, Number 3 July 1984 pp 253-259
http://keithp.com/~keithp/porterduff/p253-porter.pdf

View File

@@ -0,0 +1,33 @@
Cairo is free software.
Every source file in the implementation[*] of cairo is available to be
redistributed and/or modified under the terms of either the GNU Lesser
General Public License (LGPL) version 2.1 or the Mozilla Public
License (MPL) version 1.1. Some files are available under more
liberal terms, but we believe that in all cases, each file may be used
under either the LGPL or the MPL.
See the following files in this directory for the precise terms and
conditions of either license:
COPYING-LGPL-2.1
COPYING-MPL-1.1
Please see each file in the implementation for copyright and licensing
information, (in the opening comment of each file).
[*] The implementation of cairo is contained entirely within the "src"
directory of the cairo source distribution. There are other components
of the cairo source distribution (such as the "test", "util", and "perf")
that are auxiliary to the library itself. None of the source code in these
directories contributes to a build of the cairo library itself, (libcairo.so
or cairo.dll or similar).
These auxiliary components are also free software, but may be under
different license terms than cairo itself. For example, most of the
test cases in the perf and test directories are made available under
an MIT license to simplify any use of this code for reference purposes
in using cairo itself. Other files might be available under the GNU
General Public License (GPL), for example. Again, please see the COPYING
file under each directory and the opening comment of each file for copyright
and licensing information.

View File

@@ -0,0 +1,179 @@
LIBRARY = cairo2
CC = gcc
CFLAGS = -c -O2 -ffast-math -Wall -Winline -Wno-attributes -fomit-frame-pointer
LD = ld
LDFLAGS = -shared -s -nostdlib -T ../newlib/dll.lds --entry _DllStartup --image-base=0 --output-def $(LIBRARY).orig.def --out-implib $(LIBRARY).dll.a
STRIP = $(PREFIX)strip
DEFINES = -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -U_MSC_VER -DHAVE_CONFIG_H=1 -DCAIRO_NO_MUTEX=1
INCLUDES = -I. -I../newlib/include -I../pixman -I../zlib -I../libpng -I../freetype/include
LIBPATH:= -L../../lib
LIBS:= -ldll -lgcc -lfreetype.dll -lz.dll -lpixman-1.dll -lpng16.dll -lc.dll
CAIRO_SOURCES = \
cairo.c \
cairo-analysis-surface.c \
cairo-arc.c \
cairo-array.c \
cairo-atomic.c \
cairo-base64-stream.c \
cairo-base85-stream.c \
cairo-bentley-ottmann.c \
cairo-bentley-ottmann-rectangular.c \
cairo-bentley-ottmann-rectilinear.c \
cairo-botor-scan-converter.c \
cairo-boxes.c \
cairo-boxes-intersect.c \
cairo-cache.c \
cairo-cff-subset.c \
cairo-clip.c \
cairo-clip-boxes.c \
cairo-clip-polygon.c \
cairo-clip-region.c \
cairo-clip-surface.c \
cairo-clip-tor-scan-converter.c \
cairo-color.c \
cairo-composite-rectangles.c \
cairo-compositor.c \
cairo-contour.c \
cairo-damage.c \
cairo-debug.c \
cairo-default-context.c \
cairo-deflate-stream.c \
cairo-device.c \
cairo-error.c \
cairo-fallback-compositor.c \
cairo-fixed.c \
cairo-font-face.c \
cairo-font-face-twin.c \
cairo-font-face-twin-data.c \
cairo-font-options.c \
cairo-freed-pool.c \
cairo-freelist.c \
cairo-ft-font.c \
cairo-gstate.c \
cairo-hash.c \
cairo-hull.c \
cairo-image-compositor.c \
cairo-image-info.c \
cairo-image-source.c \
cairo-image-surface.c \
cairo-lzw.c \
cairo-mask-compositor.c \
cairo-matrix.c \
cairo-mempool.c \
cairo-mesh-pattern-rasterizer.c \
cairo-misc.c \
cairo-mono-scan-converter.c \
cairo-mutex.c \
cairo-no-compositor.c \
cairo-observer.c \
cairo-output-stream.c \
cairo-paginated-surface.c \
cairo-path.c \
cairo-path-bounds.c \
cairo-path-fill.c \
cairo-path-fixed.c \
cairo-path-in-fill.c \
cairo-path-stroke.c \
cairo-path-stroke-boxes.c \
cairo-path-stroke-polygon.c \
cairo-path-stroke-traps.c \
cairo-path-stroke-tristrip.c \
cairo-pattern.c \
cairo-pdf-operators.c \
cairo-pdf-shading.c \
cairo-pen.c \
cairo-png.c \
cairo-polygon.c \
cairo-polygon-intersect.c \
cairo-polygon-reduce.c \
cairo-raster-source-pattern.c \
cairo-recording-surface.c \
cairo-rectangle.c \
cairo-rectangular-scan-converter.c \
cairo-region.c \
cairo-rtree.c \
cairo-scaled-font.c \
cairo-scaled-font-subsets.c \
cairo-script-surface.c \
cairo-shape-mask-compositor.c \
cairo-slope.c \
cairo-spans.c \
cairo-spans-compositor.c \
cairo-spline.c \
cairo-stroke-dash.c \
cairo-stroke-style.c \
cairo-surface.c \
cairo-surface-clipper.c \
cairo-surface-fallback.c \
cairo-surface-offset.c \
cairo-surface-snapshot.c \
cairo-surface-subsurface.c \
cairo-surface-wrapper.c \
cairo-svg-surface.c \
cairo-tor22-scan-converter.c \
cairo-tor-scan-converter.c \
cairo-toy-font-face.c \
cairo-traps.c \
cairo-traps-compositor.c \
cairo-tristrip.c \
cairo-truetype-subset.c \
cairo-type1-fallback.c \
cairo-type1-glyph-names.c \
cairo-type1-subset.c \
cairo-type3-glyph-surface.c \
cairo-unicode.c \
cairo-user-font.c \
cairo-version.c \
cairo-wideint.c \
$(NULL)
SOURCES= $(CAIRO_SOURCES)
OBJECTS = $(patsubst %.c, src/%.o, $(SOURCES))
# targets
all: $(LIBRARY).a $(LIBRARY).dll
$(LIBRARY).a: $(OBJECTS) Makefile
ar cvrs $(LIBRARY).a $(OBJECTS)
mv -f $(LIBRARY).a ../../static
$(LIBRARY).dll: $(OBJECTS) Makefile
$(LD) $(LDFLAGS) $(LIBPATH) -o $@ $(OBJECTS) $(LIBS)
$(STRIP) $@
sed -e "s/ @[^ ]*//" $(LIBRARY).orig.def > $(LIBRARY).def
sed -f ../newlib/cmd1.sed $(LIBRARY).def > mem
sed -f ../newlib/cmd2.sed mem >$(LIBRARY).inc
mv -f $@ ../../bin
mv -f $(LIBRARY).dll.a ../../lib
%.o : %.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
clean:
-rm -f */*.o

View File

@@ -0,0 +1,179 @@
LIBRARY = cairo2
CC = gcc
CFLAGS = -c -O2 -march=pentium-mmx -ffast-math -Wall -Winline -Wno-attributes -fomit-frame-pointer
LD = ld
LDFLAGS = -shared -s -nostdlib -T ../newlib/dll.lds --entry _DllStartup --image-base=0 --output-def $(LIBRARY).orig.def --out-implib $(LIBRARY).dll.a
STRIP = $(PREFIX)strip
DEFINES = -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -U_MSC_VER -DHAVE_CONFIG_H=1 -DCAIRO_NO_MUTEX=1
INCLUDES = -I. -I../newlib/include -I../pixman -I../zlib -I../libpng -I../freetype/include
LIBPATH:= -L../../import -L../../static
LIBS:= -ldll -lgcc -lfreetype.dll -lz.dll -lpixman-1.dll -lpng16.dll -lc.dll
CAIRO_SOURCES = \
cairo.c \
cairo-analysis-surface.c \
cairo-arc.c \
cairo-array.c \
cairo-atomic.c \
cairo-base64-stream.c \
cairo-base85-stream.c \
cairo-bentley-ottmann.c \
cairo-bentley-ottmann-rectangular.c \
cairo-bentley-ottmann-rectilinear.c \
cairo-botor-scan-converter.c \
cairo-boxes.c \
cairo-boxes-intersect.c \
cairo-cache.c \
cairo-cff-subset.c \
cairo-clip.c \
cairo-clip-boxes.c \
cairo-clip-polygon.c \
cairo-clip-region.c \
cairo-clip-surface.c \
cairo-clip-tor-scan-converter.c \
cairo-color.c \
cairo-composite-rectangles.c \
cairo-compositor.c \
cairo-contour.c \
cairo-damage.c \
cairo-debug.c \
cairo-default-context.c \
cairo-deflate-stream.c \
cairo-device.c \
cairo-error.c \
cairo-fallback-compositor.c \
cairo-fixed.c \
cairo-font-face.c \
cairo-font-face-twin.c \
cairo-font-face-twin-data.c \
cairo-font-options.c \
cairo-freed-pool.c \
cairo-freelist.c \
cairo-ft-font.c \
cairo-gstate.c \
cairo-hash.c \
cairo-hull.c \
cairo-image-compositor.c \
cairo-image-info.c \
cairo-image-source.c \
cairo-image-surface.c \
cairo-lzw.c \
cairo-mask-compositor.c \
cairo-matrix.c \
cairo-mempool.c \
cairo-mesh-pattern-rasterizer.c \
cairo-misc.c \
cairo-mono-scan-converter.c \
cairo-mutex.c \
cairo-no-compositor.c \
cairo-observer.c \
cairo-output-stream.c \
cairo-paginated-surface.c \
cairo-path.c \
cairo-path-bounds.c \
cairo-path-fill.c \
cairo-path-fixed.c \
cairo-path-in-fill.c \
cairo-path-stroke.c \
cairo-path-stroke-boxes.c \
cairo-path-stroke-polygon.c \
cairo-path-stroke-traps.c \
cairo-path-stroke-tristrip.c \
cairo-pattern.c \
cairo-pdf-operators.c \
cairo-pdf-shading.c \
cairo-pen.c \
cairo-png.c \
cairo-polygon.c \
cairo-polygon-intersect.c \
cairo-polygon-reduce.c \
cairo-raster-source-pattern.c \
cairo-recording-surface.c \
cairo-rectangle.c \
cairo-rectangular-scan-converter.c \
cairo-region.c \
cairo-rtree.c \
cairo-scaled-font.c \
cairo-scaled-font-subsets.c \
cairo-script-surface.c \
cairo-shape-mask-compositor.c \
cairo-slope.c \
cairo-spans.c \
cairo-spans-compositor.c \
cairo-spline.c \
cairo-stroke-dash.c \
cairo-stroke-style.c \
cairo-surface.c \
cairo-surface-clipper.c \
cairo-surface-fallback.c \
cairo-surface-offset.c \
cairo-surface-snapshot.c \
cairo-surface-subsurface.c \
cairo-surface-wrapper.c \
cairo-svg-surface.c \
cairo-tor22-scan-converter.c \
cairo-tor-scan-converter.c \
cairo-toy-font-face.c \
cairo-traps.c \
cairo-traps-compositor.c \
cairo-tristrip.c \
cairo-truetype-subset.c \
cairo-type1-fallback.c \
cairo-type1-glyph-names.c \
cairo-type1-subset.c \
cairo-type3-glyph-surface.c \
cairo-unicode.c \
cairo-user-font.c \
cairo-version.c \
cairo-wideint.c \
$(NULL)
SOURCES= $(CAIRO_SOURCES)
OBJECTS = $(patsubst %.c, src/%.o, $(SOURCES))
# targets
all: $(LIBRARY).a $(LIBRARY).dll
$(LIBRARY).a: $(OBJECTS) Makefile
ar cvrs $(LIBRARY).a $(OBJECTS)
mv -f $(LIBRARY).a ../../static
$(LIBRARY).dll: $(OBJECTS) Makefile
$(LD) $(LDFLAGS) $(LIBPATH) -o $@ $(OBJECTS) $(LIBS)
$(STRIP) $@
sed -e "s/ @[^ ]*//" $(LIBRARY).orig.def > $(LIBRARY).def
sed -f ../newlib/cmd1.sed $(LIBRARY).def > mem
sed -f ../newlib/cmd2.sed mem >$(LIBRARY).inc
mv -f $@ ../../lib
mv -f $(LIBRARY).dll.a ../../import
%.o : %.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
clean:
-rm -f */*.o

View File

@@ -0,0 +1,194 @@
Cairo - Multi-platform 2D graphics library
http://cairographics.org
What is cairo
=============
Cairo is a 2D graphics library with support for multiple output
devices. Currently supported output targets include the X Window
System, quartz, win32, and image buffers, as well as PDF, PostScript,
and SVG file output. Experimental backends include OpenGL, XCB, BeOS,
OS/2, and DirectFB.
Cairo is designed to produce consistent output on all output media
while taking advantage of display hardware acceleration when available
(for example, through the X Render Extension).
The cairo API provides operations similar to the drawing operators of
PostScript and PDF. Operations in cairo include stroking and filling
cubic Bézier splines, transforming and compositing translucent images,
and antialiased text rendering. All drawing operations can be
transformed by any affine transformation (scale, rotation, shear,
etc.).
Cairo has been designed to let you draw anything you want in a modern
2D graphical user interface. At the same time, the cairo API has been
designed to be as fun and easy to learn as possible. If you're not
having fun while programming with cairo, then we have failed
somewhere---let us know and we'll try to fix it next time around.
Cairo is free software and is available to be redistributed and/or
modified under the terms of either the GNU Lesser General Public
License (LGPL) version 2.1 or the Mozilla Public License (MPL) version
1.1.
Where to get more information about cairo
=========================================
The primary source of information about cairo is:
http://cairographics.org/
The latest versions of cairo can always be found at:
http://cairographics.org/download
Documentation on using cairo and frequently-asked questions:
http://cairographics.org/documentation
http://cairographics.org/FAQ
Mailing lists for contacting cairo users and developers:
http://cairographics.org/lists
Roadmap and unscheduled things to do, (please feel free to help out):
http://cairographics.org/roadmap
http://cairographics.org/todo
Dependencies
============
The set of libraries needed to compile cairo depends on which backends
are enabled when cairo is configured. So look at the list below to
determine which dependencies are needed for the backends of interest.
For the surface backends, we have both "supported" and "experimental"
backends. Further, the supported backends can be divided into the
"standard" backends which can be easily built on any platform, and the
"platform" backends which depend on some underlying platform-specific
system, (such as the X Window System or some other window system).
As an example, for a standard Linux build, (with image, png, pdf,
PostScript, svg, and xlib surface backends, and the freetype font
backend), the following sample commands will install necessary
dependencies:
Debian (and similar):
apt-get install libpng12-dev libz-dev libxrender-dev libfontconfig1-dev
Fedora (and similar):
yum install libpng-devel zlib-devel libXrender-devel fontconfig-devel
(Those commands intentionally don't install pixman from a distribution
package since if you're manually compiling cairo, then you likely want
to grab pixman from the same place at the same time and compile it as
well.)
Supported, "standard" surface backends
------------------------------------
image backend (required)
------------------------
pixman >= 0.18.4 http://cairographics.org/releases
png support (can be left out if desired, but many
----------- applications expect it to be present)
libpng http://www.libpng.org/pub/png/libpng.html
pdf backend
-----------
zlib http://www.gzip.org/zlib
postscript backend
------------------
zlib http://www.gzip.org/zlib
svg backend
-----------
[none]
Supported, "platform" surface backends
-----------------------------------
xlib backend
------------
X11 http://freedesktop.org/Software/xlibs
xlib-xrender backend
--------------------
Xrender >= 0.6 http://freedesktop.org/Software/xlibs
quartz backend
--------------
MacOS X >= 10.4 with Xcode >= 2.4
win32 backend
-------------
Microsoft Windows 2000 or newer[*].
Font backends (required to have at least one)
---------------------------------------------
freetype font backend
---------------------
freetype >= 2.1.9 http://freetype.org
fontconfig http://fontconfig.org
quartz-font backend
-------------------
MacOS X >= 10.4 with Xcode >= 2.4
win32 font backend
------------------
Microsoft Windows 2000 or newer[*].
[*] The Win32 backend should work on Windows 2000 and newer
(excluding Windows Me.) Most testing has been done on
Windows XP. While some portions of the code have been
adapted to work on older versions of Windows, considerable
work still needs to be done to get cairo running in those
environments.
Cairo can be compiled on Windows with either the gcc
toolchain (see http://www.mingw.org) or with Microsoft
Visual C++. If the gcc toolchain is used, the standard
build instructions using configure apply, (see INSTALL).
If Visual C++ is desired, GNU make is required and
Makefile.win32 can be used via 'make -f Makefile.win32'.
The compiler, include paths, and library paths must be set
up correctly in the environment.
MSVC versions earlier than 7.1 are known to miscompile
parts of cairo and pixman, and so should be avoided. MSVC
7.1 or later, including the free Microsoft Visual Studio
Express editions, produce correct code.
Experimental surface backends
-----------------------------
xcb backend
-----------
XCB http://xcb.freedesktop.org
beos backend
------------
No dependencies in itself other than an installed BeOS system, but cairo
requires a font backend. See the freetype dependency list.
os2 backend
-----------
Cairo should run on any recent version of OS/2 or eComStation, but it
requires a font backend. See the freetype dependency list. Ready to use
packages and developer dependencies are available at Netlabs:
ftp://ftp.netlabs.org/pub/cairo
Compiling
=========
See the INSTALL document for build instructions.
History
=======
Cairo was originally developed by Carl Worth <cworth@cworth.org> and
Keith Packard <keithp@keithp.com>. Many thanks are due to Lyle Ramshaw
without whose patient help our ignorance would be much more apparent.
Since the original development, many more people have contributed to
cairo. See the AUTHORS files for as complete a list as we've been able
to compile so far.

View File

@@ -0,0 +1,8 @@
#ifndef CAIRO_VERSION_H
#define CAIRO_VERSION_H
#define CAIRO_VERSION_MAJOR 1
#define CAIRO_VERSION_MINOR 12
#define CAIRO_VERSION_MICRO 16
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,391 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* whether memory barriers are needed around atomic operations */
/* #undef ATOMIC_OP_NEEDS_MEMORY_BARRIER */
/* Define to 1 if the PDF backend can be tested (need poppler and other
dependencies for pdf2png) */
/* #undef CAIRO_CAN_TEST_PDF_SURFACE */
/* Define to 1 if the PS backend can be tested (needs ghostscript) */
//#define CAIRO_CAN_TEST_PS_SURFACE 1
/* Define to 1 if the SVG backend can be tested */
/* #undef CAIRO_CAN_TEST_SVG_SURFACE */
/* Define to 1 if the Win32 Printing backend can be tested (needs ghostscript)
*/
/* #undef CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE */
/* Define to 1 to enable cairo's cairo-script-interpreter feature */
//#define CAIRO_HAS_INTERPRETER 1
/* Define to 1 to enable cairo's cairo-perf-utils feature */
/* #undef CAIRO_HAS_PERF_UTILS */
/* Define to 1 to enable cairo's pthread feature */
/* #undef CAIRO_HAS_PTHREAD */
/* Define to 1 if we have full pthread support */
/* #undef CAIRO_HAS_REAL_PTHREAD */
/* Define to 1 if libspectre is available */
/* #undef CAIRO_HAS_SPECTRE */
/* Define to 1 to enable cairo's symbol-lookup feature */
/* #undef CAIRO_HAS_SYMBOL_LOOKUP */
/* Define to 1 to enable cairo's test surfaces feature */
/* #undef CAIRO_HAS_TEST_SURFACES */
/* Define to 1 to enable cairo's cairo-trace feature */
/* #undef CAIRO_HAS_TRACE */
/* Define to 1 to disable certain code paths that rely heavily on double
precision floating-point calculation */
#define DISABLE_SOME_FLOATING_POINT 1
/* Define to 1 if your system stores words within floats with the most
significant word first */
/* #undef FLOAT_WORDS_BIGENDIAN */
/* Enable pixman glyph cache */
#define HAS_PIXMAN_GLYPHS 1
/* Define to 1 if you have the `alarm' function. */
//#define HAVE_ALARM 1
/* Define to 1 if you have the binutils development files installed */
/* #undef HAVE_BFD */
/* Define to 1 if your compiler supports the __builtin_return_address()
intrinsic. */
#define HAVE_BUILTIN_RETURN_ADDRESS 1
/* Define to 1 if you have the <byteswap.h> header file. */
//#define HAVE_BYTESWAP_H 1
/* Define to 1 if you have the `clock_gettime' function. */
//#define HAVE_CLOCK_GETTIME 1
/* Define to 1 if you have the `ctime_r' function. */
//#define HAVE_CTIME_R 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `drand48' function. */
#define HAVE_DRAND48 1
/* Define to 1 if you have the `FcFini' function. */
/* #undef HAVE_FCFINI */
/* Define to 1 if you have the `FcInit' function. */
/* #undef HAVE_FCINIT */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `feclearexcept' function. */
#define HAVE_FECLEAREXCEPT 1
/* Define to 1 if you have the `fedisableexcept' function. */
#define HAVE_FEDISABLEEXCEPT 1
/* Define to 1 if you have the `feenableexcept' function. */
#define HAVE_FEENABLEEXCEPT 1
/* Define to 1 if you have the <fenv.h> header file. */
#define HAVE_FENV_H 1
/* Define to 1 if you have the `flockfile' function. */
#define HAVE_FLOCKFILE 1
/* Define to 1 if you have the `fork' function. */
//#define HAVE_FORK 1
/* Define to 1 if you have the `FT_Get_X11_Font_Format' function. */
//#define HAVE_FT_GET_X11_FONT_FORMAT 1
/* Define to 1 if you have the `FT_GlyphSlot_Embolden' function. */
#define HAVE_FT_GLYPHSLOT_EMBOLDEN 1
/* Define to 1 if you have the `FT_GlyphSlot_Oblique' function. */
#define HAVE_FT_GLYPHSLOT_OBLIQUE 1
/* Define to 1 if you have the `FT_Library_SetLcdFilter' function. */
//#define HAVE_FT_LIBRARY_SETLCDFILTER 1
/* Define to 1 if you have the `FT_Load_Sfnt_Table' function. */
#define HAVE_FT_LOAD_SFNT_TABLE 1
/* Define to 1 if you have the `funlockfile' function. */
//#define HAVE_FUNLOCKFILE 1
/* Whether you have gcov */
/* #undef HAVE_GCOV */
/* Define to 1 if you have the `getline' function. */
//#define HAVE_GETLINE 1
/* Enable if your compiler supports the Intel __sync_* atomic primitives */
//#define HAVE_INTEL_ATOMIC_PRIMITIVES 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <io.h> header file. */
/* #undef HAVE_IO_H */
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
/* Define to 1 if you have the `rt' library (-lrt). */
//#define HAVE_LIBRT 1
/* Enable if you have libatomic-ops-dev installed */
/* #undef HAVE_LIB_ATOMIC_OPS */
/* Define to 1 if you have the `link' function. */
//#define HAVE_LINK 1
/* Define to 1 if you have the Valgrind lockdep tool */
/* #undef HAVE_LOCKDEP */
/* Define to 1 if you have lzo available */
//#define HAVE_LZO 1
/* Define to 1 if you have the Valgrind memfault tool */
/* #undef HAVE_MEMFAULT */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to non-zero if your system has mkdir, and to 2 if your version of
mkdir requires a mode parameter */
//#define HAVE_MKDIR 2
/* Define to 1 if you have the `mmap' function. */
//#define HAVE_MMAP 1
/* Enable if you have MacOS X atomic operations */
/* #undef HAVE_OS_ATOMIC_OPS */
/* Define to 1 if you have the `poppler_page_render' function. */
/* #undef HAVE_POPPLER_PAGE_RENDER */
/* Define to 1 if you have the `raise' function. */
//#define HAVE_RAISE 1
/* Define to 1 if you have the `rsvg_pixbuf_from_file' function. */
/* #undef HAVE_RSVG_PIXBUF_FROM_FILE */
/* Define to 1 if you have the `sched_getaffinity' function. */
//#define HAVE_SCHED_GETAFFINITY 1
/* Define to 1 if you have the <sched.h> header file. */
//#define HAVE_SCHED_H 1
/* Define to 1 if you have the <setjmp.h> header file. */
#define HAVE_SETJMP_H 1
/* Define to 1 if you have the <signal.h> header file. */
//#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strndup' function. */
//#define HAVE_STRNDUP 1
/* Define to 1 if you have the <sys/int_types.h> header file. */
/* #undef HAVE_SYS_INT_TYPES_H */
/* Define to 1 if you have the <sys/ioctl.h> header file. */
//#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/poll.h> header file. */
#define HAVE_SYS_POLL_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1
/* Define to 1 if you have the <sys/wait.h> header file. */
//#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if the system has the type `uint128_t'. */
/* #undef HAVE_UINT128_T */
/* Define to 1 if the system has the type `uint64_t'. */
#define HAVE_UINT64_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have Valgrind */
/* #undef HAVE_VALGRIND */
/* Define to 1 if you have the `waitpid' function. */
//#define HAVE_WAITPID 1
/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */
/* Define to 1 if you have zlib available */
#define HAVE_ZLIB 1
/* Define to 1 if the system has the type `__uint128_t'. */
/* #undef HAVE___UINT128_T */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://bugs.freedesktop.org/enter_bug.cgi?product=cairo"
/* Define to the full name of this package. */
#define PACKAGE_NAME USE_cairo_INSTEAD
/* Define to the full name and version of this package. */
#define PACKAGE_STRING USE_cairo_version_OR_cairo_version_string_INSTEAD
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME USE_cairo_INSTEAD
/* Define to the home page for this package. */
#define PACKAGE_URL "http://cairographics.org/"
/* Define to the version of this package. */
#define PACKAGE_VERSION USE_cairo_version_OR_cairo_version_string_INSTEAD
/* Shared library file extension */
#define SHARED_LIB_EXT "dll"
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG 4
/* The size of `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 4
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Define to the value your compiler uses to support the warn-unused-result
attribute */
#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Deal with multiple architecture compiles on Mac OS X */
#ifdef __APPLE_CC__
#ifdef __BIG_ENDIAN__
#define WORDS_BIGENDIAN 1
#define FLOAT_WORDS_BIGENDIAN 1
#else
/* #undef WORDS_BIGENDIAN */
/* #undef FLOAT_WORDS_BIGENDIAN */
#endif
#endif
/* Define to 1 if the X Window System is missing or not being used. */
/* #undef X_DISPLAY_MISSING */
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
Cairo Library Source Code
=========================
This directory contains the source code of the cairo library.
Source Code Listing
-------------------
The canonical list of source files is the file Makefile.sources. See that
file for how it works.
New Backends
------------
The rule of the thumb for adding new backends is to see how other
backends are integrated. Pick one of the simpler, unsupported, backends
and search the entire tree for it, and go from there.
To add new backends you need to basically:
* Modify $(top_srcdir)/configure.in to add checks for your backend.
* Modify Makefile.sources to add source files for your backend,
* Modify $(top_srcdir)/boilerplate/ to add boilerplate code for
testing your new backend.
New API
-------
After adding new API, run "make check" in this directory and fix any
reported issues. Also add new API to the right location in
$(top_srcdir)/doc/public/cairo-sections.txt and run "make check"
in $(top_builddir)/doc/public to make sure that any newly added
documentation is correctly hooked up.
Do not forget to add tests for the new API. See next section.
Tests
-----
There are some tests in this directory that check the source code and
the build for various issues. The tests are very quick to run, and
particularly should be run after any documentation or API changes. It
does not hurt to run them after any source modification either. Run
them simply by calling:
make check
There are also extensive regression tests in $(top_srcdir)/test. It is
a good idea to run that test suite for any changes made to the source
code. Moreover, for any new feature, API, or bug fix, new tests should
be added to the regression test suite to test the new code.
Bibliography
------------
A detailed list of academic publications used in cairo code is available
in the file $(top_srcdir)/BIBLIOGRAPHY. Feel free to update as you
implement more papers.
For more technical publications (eg. Adobe technical reports) just
point them out in a comment in the header of the file implementing them.

View File

@@ -0,0 +1,74 @@
/*
* Copyright © 2005 Keith Packard
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Keith Packard
*
* Contributor(s):
* Keith Packard <keithp@keithp.com>
*/
#ifndef CAIRO_ANALYSIS_SURFACE_H
#define CAIRO_ANALYSIS_SURFACE_H
#include "cairoint.h"
cairo_private cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t *target);
cairo_private void
_cairo_analysis_surface_set_ctm (cairo_surface_t *surface,
const cairo_matrix_t *ctm);
cairo_private void
_cairo_analysis_surface_get_ctm (cairo_surface_t *surface,
cairo_matrix_t *ctm);
cairo_private cairo_region_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
cairo_private cairo_region_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *surface);
cairo_private cairo_bool_t
_cairo_analysis_surface_has_supported (cairo_surface_t *surface);
cairo_private cairo_bool_t
_cairo_analysis_surface_has_unsupported (cairo_surface_t *surface);
cairo_private void
_cairo_analysis_surface_get_bounding_box (cairo_surface_t *surface,
cairo_box_t *bbox);
cairo_private cairo_int_status_t
_cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
cairo_int_status_t status_b);
cairo_private cairo_surface_t *
_cairo_null_surface_create (cairo_content_t content);
#endif /* CAIRO_ANALYSIS_SURFACE_H */

View File

@@ -0,0 +1,934 @@
/*
* Copyright © 2006 Keith Packard
* Copyright © 2007 Adrian Johnson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Keith Packard
*
* Contributor(s):
* Keith Packard <keithp@keithp.com>
* Adrian Johnson <ajohnson@redneon.com>
*/
#include "cairoint.h"
#include "cairo-analysis-surface-private.h"
#include "cairo-box-inline.h"
#include "cairo-default-context-private.h"
#include "cairo-error-private.h"
#include "cairo-paginated-private.h"
#include "cairo-recording-surface-inline.h"
#include "cairo-surface-snapshot-inline.h"
#include "cairo-surface-subsurface-inline.h"
#include "cairo-region-private.h"
typedef struct {
cairo_surface_t base;
cairo_surface_t *target;
cairo_bool_t first_op;
cairo_bool_t has_supported;
cairo_bool_t has_unsupported;
cairo_region_t supported_region;
cairo_region_t fallback_region;
cairo_box_t page_bbox;
cairo_bool_t has_ctm;
cairo_matrix_t ctm;
} cairo_analysis_surface_t;
cairo_int_status_t
_cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
cairo_int_status_t status_b)
{
/* fatal errors should be checked and propagated at source */
assert (! _cairo_int_status_is_error (status_a));
assert (! _cairo_int_status_is_error (status_b));
/* return the most important status */
if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
status_b == CAIRO_INT_STATUS_UNSUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (status_a == CAIRO_INT_STATUS_IMAGE_FALLBACK ||
status_b == CAIRO_INT_STATUS_IMAGE_FALLBACK)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
if (status_a == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN ||
status_b == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
if (status_a == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
status_b == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
/* at this point we have checked all the valid internal codes, so... */
assert (status_a == CAIRO_INT_STATUS_SUCCESS &&
status_b == CAIRO_INT_STATUS_SUCCESS);
return CAIRO_INT_STATUS_SUCCESS;
}
struct proxy {
cairo_surface_t base;
cairo_surface_t *target;
};
static cairo_status_t
proxy_finish (void *abstract_surface)
{
return CAIRO_STATUS_SUCCESS;
}
static const cairo_surface_backend_t proxy_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
proxy_finish,
};
static cairo_surface_t *
attach_proxy (cairo_surface_t *source,
cairo_surface_t *target)
{
struct proxy *proxy;
proxy = malloc (sizeof (*proxy));
if (unlikely (proxy == NULL))
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
_cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content);
proxy->target = target;
_cairo_surface_attach_snapshot (source, &proxy->base, NULL);
return &proxy->base;
}
static void
detach_proxy (cairo_surface_t *proxy)
{
cairo_surface_finish (proxy);
cairo_surface_destroy (proxy);
}
static cairo_int_status_t
_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
const cairo_pattern_t *pattern)
{
const cairo_surface_pattern_t *surface_pattern;
cairo_analysis_surface_t *tmp;
cairo_surface_t *source, *proxy;
cairo_matrix_t p2d;
cairo_status_t status, analysis_status;
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
surface_pattern = (const cairo_surface_pattern_t *) pattern;
assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
source = surface_pattern->surface;
proxy = _cairo_surface_has_snapshot (source, &proxy_backend);
if (proxy != NULL) {
/* nothing untoward found so far */
return CAIRO_STATUS_SUCCESS;
}
tmp = (cairo_analysis_surface_t *)
_cairo_analysis_surface_create (surface->target);
if (unlikely (tmp->base.status))
return tmp->base.status;
proxy = attach_proxy (source, &tmp->base);
p2d = pattern->matrix;
status = cairo_matrix_invert (&p2d);
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm);
tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm);
source = _cairo_surface_get_source (source, NULL);
status = _cairo_recording_surface_replay_and_create_regions (source,
&tmp->base);
analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS;
detach_proxy (proxy);
cairo_surface_destroy (&tmp->base);
if (unlikely (status))
return status;
return analysis_status;
}
static cairo_int_status_t
_add_operation (cairo_analysis_surface_t *surface,
cairo_rectangle_int_t *rect,
cairo_int_status_t backend_status)
{
cairo_int_status_t status;
cairo_box_t bbox;
if (rect->width == 0 || rect->height == 0) {
/* Even though the operation is not visible we must be careful
* to not allow unsupported operations to be replayed to the
* backend during CAIRO_PAGINATED_MODE_RENDER */
if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
backend_status == CAIRO_INT_STATUS_NOTHING_TO_DO)
{
return CAIRO_INT_STATUS_SUCCESS;
}
else
{
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
}
}
_cairo_box_from_rectangle (&bbox, rect);
if (surface->has_ctm) {
int tx, ty;
if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) {
rect->x += tx;
rect->y += ty;
tx = _cairo_fixed_from_int (tx);
bbox.p1.x += tx;
bbox.p2.x += tx;
ty = _cairo_fixed_from_int (ty);
bbox.p1.y += ty;
bbox.p2.y += ty;
} else {
_cairo_matrix_transform_bounding_box_fixed (&surface->ctm,
&bbox, NULL);
if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
/* Even though the operation is not visible we must be
* careful to not allow unsupported operations to be
* replayed to the backend during
* CAIRO_PAGINATED_MODE_RENDER */
if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
backend_status == CAIRO_INT_STATUS_NOTHING_TO_DO)
{
return CAIRO_INT_STATUS_SUCCESS;
}
else
{
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
}
}
_cairo_box_round_to_rectangle (&bbox, rect);
}
}
if (surface->first_op) {
surface->first_op = FALSE;
surface->page_bbox = bbox;
} else
_cairo_box_add_box(&surface->page_bbox, &bbox);
/* If the operation is completely enclosed within the fallback
* region there is no benefit in emitting a native operation as
* the fallback image will be painted on top.
*/
if (cairo_region_contains_rectangle (&surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) {
/* A status of CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY indicates
* that the backend only supports this operation if the
* transparency removed. If the extents of this operation does
* not intersect any other native operation, the operation is
* natively supported and the backend will blend the
* transparency into the white background.
*/
if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT)
backend_status = CAIRO_INT_STATUS_SUCCESS;
}
if (backend_status == CAIRO_INT_STATUS_SUCCESS) {
/* Add the operation to the supported region. Operations in
* this region will be emitted as native operations.
*/
surface->has_supported = TRUE;
return cairo_region_union_rectangle (&surface->supported_region, rect);
}
/* Add the operation to the unsupported region. This region will
* be painted as an image after all native operations have been
* emitted.
*/
surface->has_unsupported = TRUE;
status = cairo_region_union_rectangle (&surface->fallback_region, rect);
/* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate
* unsupported operations to the recording surface as using
* CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to
* invoke the cairo-surface-fallback path then return
* CAIRO_STATUS_SUCCESS.
*/
if (status == CAIRO_INT_STATUS_SUCCESS)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
else
return status;
}
static cairo_status_t
_cairo_analysis_surface_finish (void *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
_cairo_region_fini (&surface->supported_region);
_cairo_region_fini (&surface->fallback_region);
cairo_surface_destroy (surface->target);
return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
_cairo_analysis_surface_get_extents (void *abstract_surface,
cairo_rectangle_int_t *rectangle)
{
cairo_analysis_surface_t *surface = abstract_surface;
return _cairo_surface_get_extents (surface->target, rectangle);
}
static void
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, const cairo_clip_t *clip)
{
if (clip != NULL)
_cairo_rectangle_intersect (extents, _cairo_clip_get_extents (clip));
}
static void
_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip,
cairo_rectangle_int_t *extents)
{
cairo_bool_t is_empty;
is_empty = _cairo_surface_get_extents (&surface->base, extents);
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
_cairo_pattern_get_extents (source, &source_extents);
_cairo_rectangle_intersect (extents, &source_extents);
}
_rectangle_intersect_clip (extents, clip);
}
static cairo_int_status_t
_cairo_analysis_surface_paint (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->paint == NULL) {
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
} else {
backend_status =
surface->target->backend->paint (surface->target,
op, source, clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
backend_status = _analyze_recording_surface_pattern (surface, source);
_cairo_analysis_surface_operation_extents (surface,
op, source, clip,
&extents);
return _add_operation (surface, &extents, backend_status);
}
static cairo_int_status_t
_cairo_analysis_surface_mask (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->mask == NULL) {
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
} else {
backend_status =
surface->target->backend->mask (surface->target,
op, source, mask, clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface;
src_surface = _cairo_surface_get_source (src_surface, NULL);
if (_cairo_surface_is_recording (src_surface)) {
backend_source_status =
_analyze_recording_surface_pattern (surface, source);
if (_cairo_int_status_is_error (backend_source_status))
return backend_source_status;
}
}
if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_t *mask_surface = ((cairo_surface_pattern_t *)mask)->surface;
mask_surface = _cairo_surface_get_source (mask_surface, NULL);
if (_cairo_surface_is_recording (mask_surface)) {
backend_mask_status =
_analyze_recording_surface_pattern (surface, mask);
if (_cairo_int_status_is_error (backend_mask_status))
return backend_mask_status;
}
}
backend_status =
_cairo_analysis_surface_merge_status (backend_source_status,
backend_mask_status);
}
_cairo_analysis_surface_operation_extents (surface,
op, source, clip,
&extents);
if (_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_int_t mask_extents;
_cairo_pattern_get_extents (mask, &mask_extents);
_cairo_rectangle_intersect (&extents, &mask_extents);
}
return _add_operation (surface, &extents, backend_status);
}
static cairo_int_status_t
_cairo_analysis_surface_stroke (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->stroke == NULL) {
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
} else {
backend_status =
surface->target->backend->stroke (surface->target, op,
source, path, style,
ctm, ctm_inverse,
tolerance, antialias,
clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
backend_status = _analyze_recording_surface_pattern (surface, source);
_cairo_analysis_surface_operation_extents (surface,
op, source, clip,
&extents);
if (_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_int_t mask_extents;
cairo_int_status_t status;
status = _cairo_path_fixed_stroke_extents (path, style,
ctm, ctm_inverse,
tolerance,
&mask_extents);
if (unlikely (status))
return status;
_cairo_rectangle_intersect (&extents, &mask_extents);
}
return _add_operation (surface, &extents, backend_status);
}
static cairo_int_status_t
_cairo_analysis_surface_fill (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t backend_status;
cairo_rectangle_int_t extents;
if (surface->target->backend->fill == NULL) {
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
} else {
backend_status =
surface->target->backend->fill (surface->target, op,
source, path, fill_rule,
tolerance, antialias,
clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
backend_status = _analyze_recording_surface_pattern (surface, source);
_cairo_analysis_surface_operation_extents (surface,
op, source, clip,
&extents);
if (_cairo_operator_bounded_by_mask (op)) {
cairo_rectangle_int_t mask_extents;
_cairo_path_fixed_fill_extents (path, fill_rule, tolerance,
&mask_extents);
_cairo_rectangle_intersect (&extents, &mask_extents);
}
return _add_operation (surface, &extents, backend_status);
}
static cairo_int_status_t
_cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
/* Adapted from _cairo_surface_show_glyphs */
if (surface->target->backend->show_glyphs != NULL) {
backend_status =
surface->target->backend->show_glyphs (surface->target, op,
source,
glyphs, num_glyphs,
scaled_font,
clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
else if (surface->target->backend->show_text_glyphs != NULL)
{
backend_status =
surface->target->backend->show_text_glyphs (surface->target, op,
source,
NULL, 0,
glyphs, num_glyphs,
NULL, 0,
FALSE,
scaled_font,
clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
else
{
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
}
if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
backend_status = _analyze_recording_surface_pattern (surface, source);
_cairo_analysis_surface_operation_extents (surface,
op, source, clip,
&extents);
if (_cairo_operator_bounded_by_mask (op)) {
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
&glyph_extents,
NULL);
if (unlikely (status))
return status;
_cairo_rectangle_intersect (&extents, &glyph_extents);
}
return _add_operation (surface, &extents, backend_status);
}
static cairo_bool_t
_cairo_analysis_surface_has_show_text_glyphs (void *abstract_surface)
{
cairo_analysis_surface_t *surface = abstract_surface;
return cairo_surface_has_show_text_glyphs (surface->target);
}
static cairo_int_status_t
_cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_text_cluster_t *clusters,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t status, backend_status;
cairo_rectangle_int_t extents, glyph_extents;
/* Adapted from _cairo_surface_show_glyphs */
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
if (surface->target->backend->show_text_glyphs != NULL) {
backend_status =
surface->target->backend->show_text_glyphs (surface->target, op,
source,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters,
cluster_flags,
scaled_font,
clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
surface->target->backend->show_glyphs != NULL)
{
backend_status =
surface->target->backend->show_glyphs (surface->target, op,
source,
glyphs, num_glyphs,
scaled_font,
clip);
if (_cairo_int_status_is_error (backend_status))
return backend_status;
}
if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
backend_status = _analyze_recording_surface_pattern (surface, source);
_cairo_analysis_surface_operation_extents (surface,
op, source, clip,
&extents);
if (_cairo_operator_bounded_by_mask (op)) {
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs,
num_glyphs,
&glyph_extents,
NULL);
if (unlikely (status))
return status;
_cairo_rectangle_intersect (&extents, &glyph_extents);
}
return _add_operation (surface, &extents, backend_status);
}
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
_cairo_analysis_surface_finish,
NULL,
NULL, /* create_similar */
NULL, /* create_similar_image */
NULL, /* map_to_image */
NULL, /* unmap */
NULL, /* source */
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_analysis_surface_get_extents,
NULL, /* get_font_options */
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
_cairo_analysis_surface_paint,
_cairo_analysis_surface_mask,
_cairo_analysis_surface_stroke,
_cairo_analysis_surface_fill,
NULL, /* fill_stroke */
_cairo_analysis_surface_show_glyphs,
_cairo_analysis_surface_has_show_text_glyphs,
_cairo_analysis_surface_show_text_glyphs
};
cairo_surface_t *
_cairo_analysis_surface_create (cairo_surface_t *target)
{
cairo_analysis_surface_t *surface;
cairo_status_t status;
status = target->status;
if (unlikely (status))
return _cairo_surface_create_in_error (status);
surface = malloc (sizeof (cairo_analysis_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
/* I believe the content type here is truly arbitrary. I'm quite
* sure nothing will ever use this value. */
_cairo_surface_init (&surface->base,
&cairo_analysis_surface_backend,
NULL, /* device */
CAIRO_CONTENT_COLOR_ALPHA);
cairo_matrix_init_identity (&surface->ctm);
surface->has_ctm = FALSE;
surface->target = cairo_surface_reference (target);
surface->first_op = TRUE;
surface->has_supported = FALSE;
surface->has_unsupported = FALSE;
_cairo_region_init (&surface->supported_region);
_cairo_region_init (&surface->fallback_region);
surface->page_bbox.p1.x = 0;
surface->page_bbox.p1.y = 0;
surface->page_bbox.p2.x = 0;
surface->page_bbox.p2.y = 0;
return &surface->base;
}
void
_cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface,
const cairo_matrix_t *ctm)
{
cairo_analysis_surface_t *surface;
if (abstract_surface->status)
return;
surface = (cairo_analysis_surface_t *) abstract_surface;
surface->ctm = *ctm;
surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
}
void
_cairo_analysis_surface_get_ctm (cairo_surface_t *abstract_surface,
cairo_matrix_t *ctm)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
*ctm = surface->ctm;
}
cairo_region_t *
_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return &surface->supported_region;
}
cairo_region_t *
_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return &surface->fallback_region;
}
cairo_bool_t
_cairo_analysis_surface_has_supported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return surface->has_supported;
}
cairo_bool_t
_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
return surface->has_unsupported;
}
void
_cairo_analysis_surface_get_bounding_box (cairo_surface_t *abstract_surface,
cairo_box_t *bbox)
{
cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface;
*bbox = surface->page_bbox;
}
/* null surface type: a surface that does nothing (has no side effects, yay!) */
static cairo_int_status_t
_return_success (void)
{
return CAIRO_STATUS_SUCCESS;
}
/* These typedefs are just to silence the compiler... */
typedef cairo_int_status_t
(*_paint_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_mask_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_stroke_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_fill_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip);
typedef cairo_int_status_t
(*_show_glyphs_func) (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip);
static const cairo_surface_backend_t cairo_null_surface_backend = {
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
NULL, /* finish */
NULL, /* only accessed through the surface functions */
NULL, /* create_similar */
NULL, /* create similar image */
NULL, /* map to image */
NULL, /* unmap image*/
NULL, /* source */
NULL, /* acquire_source_image */
NULL, /* release_source_image */
NULL, /* snapshot */
NULL, /* copy_page */
NULL, /* show_page */
NULL, /* get_extents */
NULL, /* get_font_options */
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
(_paint_func) _return_success, /* paint */
(_mask_func) _return_success, /* mask */
(_stroke_func) _return_success, /* stroke */
(_fill_func) _return_success, /* fill */
NULL, /* fill_stroke */
(_show_glyphs_func) _return_success, /* show_glyphs */
NULL, /* has_show_text_glyphs */
NULL /* show_text_glyphs */
};
cairo_surface_t *
_cairo_null_surface_create (cairo_content_t content)
{
cairo_surface_t *surface;
surface = malloc (sizeof (cairo_surface_t));
if (unlikely (surface == NULL)) {
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
_cairo_surface_init (surface,
&cairo_null_surface_backend,
NULL, /* device */
content);
return surface;
}

View File

@@ -0,0 +1,61 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Carl D. Worth <cworth@redhat.com>
*/
#ifndef CAIRO_ARC_PRIVATE_H
#define CAIRO_ARC_PRIVATE_H
#include "cairoint.h"
CAIRO_BEGIN_DECLS
cairo_private void
_cairo_arc_path (cairo_t *cr,
double xc,
double yc,
double radius,
double angle1,
double angle2);
cairo_private void
_cairo_arc_path_negative (cairo_t *cr,
double xc,
double yc,
double radius,
double angle1,
double angle2);
CAIRO_END_DECLS
#endif /* CAIRO_ARC_PRIVATE_H */

View File

@@ -0,0 +1,308 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
#include "cairo-arc-private.h"
#define MAX_FULL_CIRCLES 65536
/* Spline deviation from the circle in radius would be given by:
error = sqrt (x**2 + y**2) - 1
A simpler error function to work with is:
e = x**2 + y**2 - 1
From "Good approximation of circles by curvature-continuous Bezier
curves", Tor Dokken and Morten Daehlen, Computer Aided Geometric
Design 8 (1990) 22-41, we learn:
abs (max(e)) = 4/27 * sin**6(angle/4) / cos**2(angle/4)
and
abs (error) =~ 1/2 * e
Of course, this error value applies only for the particular spline
approximation that is used in _cairo_gstate_arc_segment.
*/
static double
_arc_error_normalized (double angle)
{
return 2.0/27.0 * pow (sin (angle / 4), 6) / pow (cos (angle / 4), 2);
}
static double
_arc_max_angle_for_tolerance_normalized (double tolerance)
{
double angle, error;
int i;
/* Use table lookup to reduce search time in most cases. */
struct {
double angle;
double error;
} table[] = {
{ M_PI / 1.0, 0.0185185185185185036127 },
{ M_PI / 2.0, 0.000272567143730179811158 },
{ M_PI / 3.0, 2.38647043651461047433e-05 },
{ M_PI / 4.0, 4.2455377443222443279e-06 },
{ M_PI / 5.0, 1.11281001494389081528e-06 },
{ M_PI / 6.0, 3.72662000942734705475e-07 },
{ M_PI / 7.0, 1.47783685574284411325e-07 },
{ M_PI / 8.0, 6.63240432022601149057e-08 },
{ M_PI / 9.0, 3.2715520137536980553e-08 },
{ M_PI / 10.0, 1.73863223499021216974e-08 },
{ M_PI / 11.0, 9.81410988043554039085e-09 },
};
int table_size = ARRAY_LENGTH (table);
for (i = 0; i < table_size; i++)
if (table[i].error < tolerance)
return table[i].angle;
++i;
do {
angle = M_PI / i++;
error = _arc_error_normalized (angle);
} while (error > tolerance);
return angle;
}
static int
_arc_segments_needed (double angle,
double radius,
cairo_matrix_t *ctm,
double tolerance)
{
double major_axis, max_angle;
/* the error is amplified by at most the length of the
* major axis of the circle; see cairo-pen.c for a more detailed analysis
* of this. */
major_axis = _cairo_matrix_transformed_circle_major_axis (ctm, radius);
max_angle = _arc_max_angle_for_tolerance_normalized (tolerance / major_axis);
return ceil (fabs (angle) / max_angle);
}
/* We want to draw a single spline approximating a circular arc radius
R from angle A to angle B. Since we want a symmetric spline that
matches the endpoints of the arc in position and slope, we know
that the spline control points must be:
(R * cos(A), R * sin(A))
(R * cos(A) - h * sin(A), R * sin(A) + h * cos (A))
(R * cos(B) + h * sin(B), R * sin(B) - h * cos (B))
(R * cos(B), R * sin(B))
for some value of h.
"Approximation of circular arcs by cubic polynomials", Michael
Goldapp, Computer Aided Geometric Design 8 (1991) 227-238, provides
various values of h along with error analysis for each.
From that paper, a very practical value of h is:
h = 4/3 * R * tan(angle/4)
This value does not give the spline with minimal error, but it does
provide a very good approximation, (6th-order convergence), and the
error expression is quite simple, (see the comment for
_arc_error_normalized).
*/
static void
_cairo_arc_segment (cairo_t *cr,
double xc,
double yc,
double radius,
double angle_A,
double angle_B)
{
double r_sin_A, r_cos_A;
double r_sin_B, r_cos_B;
double h;
r_sin_A = radius * sin (angle_A);
r_cos_A = radius * cos (angle_A);
r_sin_B = radius * sin (angle_B);
r_cos_B = radius * cos (angle_B);
h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0);
cairo_curve_to (cr,
xc + r_cos_A - h * r_sin_A,
yc + r_sin_A + h * r_cos_A,
xc + r_cos_B + h * r_sin_B,
yc + r_sin_B - h * r_cos_B,
xc + r_cos_B,
yc + r_sin_B);
}
static void
_cairo_arc_in_direction (cairo_t *cr,
double xc,
double yc,
double radius,
double angle_min,
double angle_max,
cairo_direction_t dir)
{
if (cairo_status (cr))
return;
assert (angle_max >= angle_min);
if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) {
angle_max = fmod (angle_max - angle_min, 2 * M_PI);
angle_min = fmod (angle_min, 2 * M_PI);
angle_max += angle_min + 2 * M_PI * MAX_FULL_CIRCLES;
}
/* Recurse if drawing arc larger than pi */
if (angle_max - angle_min > M_PI) {
double angle_mid = angle_min + (angle_max - angle_min) / 2.0;
if (dir == CAIRO_DIRECTION_FORWARD) {
_cairo_arc_in_direction (cr, xc, yc, radius,
angle_min, angle_mid,
dir);
_cairo_arc_in_direction (cr, xc, yc, radius,
angle_mid, angle_max,
dir);
} else {
_cairo_arc_in_direction (cr, xc, yc, radius,
angle_mid, angle_max,
dir);
_cairo_arc_in_direction (cr, xc, yc, radius,
angle_min, angle_mid,
dir);
}
} else if (angle_max != angle_min) {
cairo_matrix_t ctm;
int i, segments;
double step;
cairo_get_matrix (cr, &ctm);
segments = _arc_segments_needed (angle_max - angle_min,
radius, &ctm,
cairo_get_tolerance (cr));
step = (angle_max - angle_min) / segments;
segments -= 1;
if (dir == CAIRO_DIRECTION_REVERSE) {
double t;
t = angle_min;
angle_min = angle_max;
angle_max = t;
step = -step;
}
for (i = 0; i < segments; i++, angle_min += step) {
_cairo_arc_segment (cr, xc, yc, radius,
angle_min, angle_min + step);
}
_cairo_arc_segment (cr, xc, yc, radius,
angle_min, angle_max);
} else {
cairo_line_to (cr,
xc + radius * cos (angle_min),
yc + radius * sin (angle_min));
}
}
/**
* _cairo_arc_path:
* @cr: a cairo context
* @xc: X position of the center of the arc
* @yc: Y position of the center of the arc
* @radius: the radius of the arc
* @angle1: the start angle, in radians
* @angle2: the end angle, in radians
*
* Compute a path for the given arc and append it onto the current
* path within @cr. The arc will be accurate within the current
* tolerance and given the current transformation.
**/
void
_cairo_arc_path (cairo_t *cr,
double xc,
double yc,
double radius,
double angle1,
double angle2)
{
_cairo_arc_in_direction (cr, xc, yc,
radius,
angle1, angle2,
CAIRO_DIRECTION_FORWARD);
}
/**
* _cairo_arc_path_negative:
* @xc: X position of the center of the arc
* @yc: Y position of the center of the arc
* @radius: the radius of the arc
* @angle1: the start angle, in radians
* @angle2: the end angle, in radians
* @ctm: the current transformation matrix
* @tolerance: the current tolerance value
* @path: the path onto which the arc will be appended
*
* Compute a path for the given arc (defined in the negative
* direction) and append it onto the current path within @cr. The arc
* will be accurate within the current tolerance and given the current
* transformation.
**/
void
_cairo_arc_path_negative (cairo_t *cr,
double xc,
double yc,
double radius,
double angle1,
double angle2)
{
_cairo_arc_in_direction (cr, xc, yc,
radius,
angle2, angle1,
CAIRO_DIRECTION_REVERSE);
}

View File

@@ -0,0 +1,90 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#ifndef CAIRO_ARRAY_PRIVATE_H
#define CAIRO_ARRAY_PRIVATE_H
#include "cairo-compiler-private.h"
#include "cairo-types-private.h"
CAIRO_BEGIN_DECLS
/* cairo-array.c structures and functions */
cairo_private void
_cairo_array_init (cairo_array_t *array, unsigned int element_size);
cairo_private void
_cairo_array_fini (cairo_array_t *array);
cairo_private cairo_status_t
_cairo_array_grow_by (cairo_array_t *array, unsigned int additional);
cairo_private void
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements);
cairo_private cairo_status_t
_cairo_array_append (cairo_array_t *array, const void *element);
cairo_private cairo_status_t
_cairo_array_append_multiple (cairo_array_t *array,
const void *elements,
unsigned int num_elements);
cairo_private cairo_status_t
_cairo_array_allocate (cairo_array_t *array,
unsigned int num_elements,
void **elements);
cairo_private void *
_cairo_array_index (cairo_array_t *array, unsigned int index);
cairo_private const void *
_cairo_array_index_const (const cairo_array_t *array, unsigned int index);
cairo_private void
_cairo_array_copy_element (const cairo_array_t *array, unsigned int index, void *dst);
cairo_private unsigned int
_cairo_array_num_elements (const cairo_array_t *array);
cairo_private unsigned int
_cairo_array_size (const cairo_array_t *array);
CAIRO_END_DECLS
#endif /* CAIRO_ARRAY_PRIVATE_H */

View File

@@ -0,0 +1,526 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#include "cairoint.h"
#include "cairo-array-private.h"
#include "cairo-error-private.h"
/**
* _cairo_array_init:
*
* Initialize a new #cairo_array_t object to store objects each of size
* @element_size.
*
* The #cairo_array_t object provides grow-by-doubling storage. It
* never interprets the data passed to it, nor does it provide any
* sort of callback mechanism for freeing resources held onto by
* stored objects.
*
* When finished using the array, _cairo_array_fini() should be
* called to free resources allocated during use of the array.
**/
void
_cairo_array_init (cairo_array_t *array, unsigned int element_size)
{
array->size = 0;
array->num_elements = 0;
array->element_size = element_size;
array->elements = NULL;
}
/**
* _cairo_array_fini:
* @array: A #cairo_array_t
*
* Free all resources associated with @array. After this call, @array
* should not be used again without a subsequent call to
* _cairo_array_init() again first.
**/
void
_cairo_array_fini (cairo_array_t *array)
{
free (array->elements);
}
/**
* _cairo_array_grow_by:
* @array: a #cairo_array_t
*
* Increase the size of @array (if needed) so that there are at least
* @additional free spaces in the array. The actual size of the array
* is always increased by doubling as many times as necessary.
**/
cairo_status_t
_cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
{
char *new_elements;
unsigned int old_size = array->size;
unsigned int required_size = array->num_elements + additional;
unsigned int new_size;
/* check for integer overflow */
if (required_size > INT_MAX || required_size < array->num_elements)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (CAIRO_INJECT_FAULT ())
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (required_size <= old_size)
return CAIRO_STATUS_SUCCESS;
if (old_size == 0)
new_size = 1;
else
new_size = old_size * 2;
while (new_size < required_size)
new_size = new_size * 2;
array->size = new_size;
new_elements = _cairo_realloc_ab (array->elements,
array->size, array->element_size);
if (unlikely (new_elements == NULL)) {
array->size = old_size;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
array->elements = new_elements;
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_array_truncate:
* @array: a #cairo_array_t
*
* Truncate size of the array to @num_elements if less than the
* current size. No memory is actually freed. The stored objects
* beyond @num_elements are simply "forgotten".
**/
void
_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
{
if (num_elements < array->num_elements)
array->num_elements = num_elements;
}
/**
* _cairo_array_index:
* @array: a #cairo_array_t
* Returns: A pointer to the object stored at @index.
*
* If the resulting value is assigned to a pointer to an object of the same
* element_size as initially passed to _cairo_array_init() then that
* pointer may be used for further direct indexing with []. For
* example:
*
* <informalexample><programlisting>
* cairo_array_t array;
* double *values;
*
* _cairo_array_init (&array, sizeof(double));
* ... calls to _cairo_array_append() here ...
*
* values = _cairo_array_index (&array, 0);
* for (i = 0; i < _cairo_array_num_elements (&array); i++)
* ... use values[i] here ...
* </programlisting></informalexample>
**/
void *
_cairo_array_index (cairo_array_t *array, unsigned int index)
{
/* We allow an index of 0 for the no-elements case.
* This makes for cleaner calling code which will often look like:
*
* elements = _cairo_array_index (array, 0);
* for (i=0; i < num_elements; i++) {
* ... use elements[i] here ...
* }
*
* which in the num_elements==0 case gets the NULL pointer here,
* but never dereferences it.
*/
if (index == 0 && array->num_elements == 0)
return NULL;
assert (index < array->num_elements);
return array->elements + index * array->element_size;
}
/**
* _cairo_array_index_const:
* @array: a #cairo_array_t
* Returns: A pointer to the object stored at @index.
*
* If the resulting value is assigned to a pointer to an object of the same
* element_size as initially passed to _cairo_array_init() then that
* pointer may be used for further direct indexing with []. For
* example:
*
* <informalexample><programlisting>
* cairo_array_t array;
* const double *values;
*
* _cairo_array_init (&array, sizeof(double));
* ... calls to _cairo_array_append() here ...
*
* values = _cairo_array_index_const (&array, 0);
* for (i = 0; i < _cairo_array_num_elements (&array); i++)
* ... read values[i] here ...
* </programlisting></informalexample>
**/
const void *
_cairo_array_index_const (const cairo_array_t *array, unsigned int index)
{
/* We allow an index of 0 for the no-elements case.
* This makes for cleaner calling code which will often look like:
*
* elements = _cairo_array_index_const (array, 0);
* for (i=0; i < num_elements; i++) {
* ... read elements[i] here ...
* }
*
* which in the num_elements==0 case gets the NULL pointer here,
* but never dereferences it.
*/
if (index == 0 && array->num_elements == 0)
return NULL;
assert (index < array->num_elements);
return array->elements + index * array->element_size;
}
/**
* _cairo_array_copy_element:
* @array: a #cairo_array_t
*
* Copy a single element out of the array from index @index into the
* location pointed to by @dst.
**/
void
_cairo_array_copy_element (const cairo_array_t *array,
unsigned int index,
void *dst)
{
memcpy (dst, _cairo_array_index_const (array, index), array->element_size);
}
/**
* _cairo_array_append:
* @array: a #cairo_array_t
*
* Append a single item onto the array by growing the array by at
* least one element, then copying element_size bytes from @element
* into the array. The address of the resulting object within the
* array can be determined with:
*
* _cairo_array_index (array, _cairo_array_num_elements (array) - 1);
*
* Return value: %CAIRO_STATUS_SUCCESS if successful or
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
* operation.
**/
cairo_status_t
_cairo_array_append (cairo_array_t *array,
const void *element)
{
return _cairo_array_append_multiple (array, element, 1);
}
/**
* _cairo_array_append_multiple:
* @array: a #cairo_array_t
*
* Append one or more items onto the array by growing the array by
* @num_elements, then copying @num_elements * element_size bytes from
* @elements into the array.
*
* Return value: %CAIRO_STATUS_SUCCESS if successful or
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
* operation.
**/
cairo_status_t
_cairo_array_append_multiple (cairo_array_t *array,
const void *elements,
unsigned int num_elements)
{
cairo_status_t status;
void *dest;
status = _cairo_array_allocate (array, num_elements, &dest);
if (unlikely (status))
return status;
memcpy (dest, elements, num_elements * array->element_size);
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_array_allocate:
* @array: a #cairo_array_t
*
* Allocate space at the end of the array for @num_elements additional
* elements, providing the address of the new memory chunk in
* @elements. This memory will be unitialized, but will be accounted
* for in the return value of _cairo_array_num_elements().
*
* Return value: %CAIRO_STATUS_SUCCESS if successful or
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
* operation.
**/
cairo_status_t
_cairo_array_allocate (cairo_array_t *array,
unsigned int num_elements,
void **elements)
{
cairo_status_t status;
status = _cairo_array_grow_by (array, num_elements);
if (unlikely (status))
return status;
assert (array->num_elements + num_elements <= array->size);
*elements = array->elements + array->num_elements * array->element_size;
array->num_elements += num_elements;
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_array_num_elements:
* @array: a #cairo_array_t
* Returns: The number of elements stored in @array.
*
* This space was left intentionally blank, but gtk-doc filled it.
**/
unsigned int
_cairo_array_num_elements (const cairo_array_t *array)
{
return array->num_elements;
}
/**
* _cairo_array_size:
* @array: a #cairo_array_t
* Returns: The number of elements for which there is currently space
* allocated in @array.
*
* This space was left intentionally blank, but gtk-doc filled it.
**/
unsigned int
_cairo_array_size (const cairo_array_t *array)
{
return array->size;
}
/**
* _cairo_user_data_array_init:
* @array: a #cairo_user_data_array_t
*
* Initializes a #cairo_user_data_array_t structure for future
* use. After initialization, the array has no keys. Call
* _cairo_user_data_array_fini() to free any allocated memory
* when done using the array.
**/
void
_cairo_user_data_array_init (cairo_user_data_array_t *array)
{
_cairo_array_init (array, sizeof (cairo_user_data_slot_t));
}
/**
* _cairo_user_data_array_fini:
* @array: a #cairo_user_data_array_t
*
* Destroys all current keys in the user data array and deallocates
* any memory allocated for the array itself.
**/
void
_cairo_user_data_array_fini (cairo_user_data_array_t *array)
{
unsigned int num_slots;
num_slots = array->num_elements;
if (num_slots) {
cairo_user_data_slot_t *slots;
slots = _cairo_array_index (array, 0);
while (num_slots--) {
cairo_user_data_slot_t *s = &slots[num_slots];
if (s->user_data != NULL && s->destroy != NULL)
s->destroy (s->user_data);
}
}
_cairo_array_fini (array);
}
/**
* _cairo_user_data_array_get_data:
* @array: a #cairo_user_data_array_t
* @key: the address of the #cairo_user_data_key_t the user data was
* attached to
*
* Returns user data previously attached using the specified
* key. If no user data has been attached with the given key this
* function returns %NULL.
*
* Return value: the user data previously attached or %NULL.
**/
void *
_cairo_user_data_array_get_data (cairo_user_data_array_t *array,
const cairo_user_data_key_t *key)
{
int i, num_slots;
cairo_user_data_slot_t *slots;
/* We allow this to support degenerate objects such as cairo_surface_nil. */
if (array == NULL)
return NULL;
num_slots = array->num_elements;
slots = _cairo_array_index (array, 0);
for (i = 0; i < num_slots; i++) {
if (slots[i].key == key)
return slots[i].user_data;
}
return NULL;
}
/**
* _cairo_user_data_array_set_data:
* @array: a #cairo_user_data_array_t
* @key: the address of a #cairo_user_data_key_t to attach the user data to
* @user_data: the user data to attach
* @destroy: a #cairo_destroy_func_t which will be called when the
* user data array is destroyed or when new user data is attached using the
* same key.
*
* Attaches user data to a user data array. To remove user data,
* call this function with the key that was used to set it and %NULL
* for @data.
*
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
* slot could not be allocated for the user data.
**/
cairo_status_t
_cairo_user_data_array_set_data (cairo_user_data_array_t *array,
const cairo_user_data_key_t *key,
void *user_data,
cairo_destroy_func_t destroy)
{
cairo_status_t status;
int i, num_slots;
cairo_user_data_slot_t *slots, *slot, new_slot;
if (user_data) {
new_slot.key = key;
new_slot.user_data = user_data;
new_slot.destroy = destroy;
} else {
new_slot.key = NULL;
new_slot.user_data = NULL;
new_slot.destroy = NULL;
}
slot = NULL;
num_slots = array->num_elements;
slots = _cairo_array_index (array, 0);
for (i = 0; i < num_slots; i++) {
if (slots[i].key == key) {
slot = &slots[i];
if (slot->destroy && slot->user_data)
slot->destroy (slot->user_data);
break;
}
if (user_data && slots[i].user_data == NULL) {
slot = &slots[i]; /* Have to keep searching for an exact match */
}
}
if (slot) {
*slot = new_slot;
return CAIRO_STATUS_SUCCESS;
}
status = _cairo_array_append (array, &new_slot);
if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_user_data_array_copy (cairo_user_data_array_t *dst,
const cairo_user_data_array_t *src)
{
/* discard any existing user-data */
if (dst->num_elements != 0) {
_cairo_user_data_array_fini (dst);
_cairo_user_data_array_init (dst);
}
return _cairo_array_append_multiple (dst,
_cairo_array_index_const (src, 0),
src->num_elements);
}
void
_cairo_user_data_array_foreach (cairo_user_data_array_t *array,
void (*func) (const void *key,
void *elt,
void *closure),
void *closure)
{
cairo_user_data_slot_t *slots;
int i, num_slots;
num_slots = array->num_elements;
slots = _cairo_array_index (array, 0);
for (i = 0; i < num_slots; i++) {
if (slots[i].user_data != NULL)
func (slots[i].key, slots[i].user_data, closure);
}
}

View File

@@ -0,0 +1,272 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2007 Chris Wilson
* Copyright © 2010 Andrea Canciani
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
* Andrea Canciani <ranma42@gmail.com>
*/
#ifndef CAIRO_ATOMIC_PRIVATE_H
#define CAIRO_ATOMIC_PRIVATE_H
# include "cairo-compiler-private.h"
#if HAVE_CONFIG_H
#include "config.h"
#endif
/* The autoconf on OpenBSD 4.5 produces the malformed constant name
* SIZEOF_VOID__ rather than SIZEOF_VOID_P. Work around that here. */
#if !defined(SIZEOF_VOID_P) && defined(SIZEOF_VOID__)
# define SIZEOF_VOID_P SIZEOF_VOID__
#endif
CAIRO_BEGIN_DECLS
#if HAVE_INTEL_ATOMIC_PRIMITIVES
#define HAS_ATOMIC_OPS 1
typedef int cairo_atomic_int_t;
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
static cairo_always_inline cairo_atomic_int_t
_cairo_atomic_int_get (cairo_atomic_int_t *x)
{
__sync_synchronize ();
return *x;
}
static cairo_always_inline void *
_cairo_atomic_ptr_get (void **x)
{
__sync_synchronize ();
return *x;
}
#else
# define _cairo_atomic_int_get(x) (*x)
# define _cairo_atomic_ptr_get(x) (*x)
#endif
# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
# define _cairo_atomic_int_dec(x) ((void) __sync_fetch_and_add(x, -1))
# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_bool_compare_and_swap (x, oldv, newv)
# define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
#if SIZEOF_VOID_P==SIZEOF_INT
typedef int cairo_atomic_intptr_t;
#elif SIZEOF_VOID_P==SIZEOF_LONG
typedef long cairo_atomic_intptr_t;
#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
typedef long long cairo_atomic_intptr_t;
#else
#error No matching integer pointer type
#endif
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
__sync_bool_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
# define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
_cairo_atomic_intptr_to_voidptr (__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv))
#endif
#if HAVE_LIB_ATOMIC_OPS
#include <atomic_ops.h>
#define HAS_ATOMIC_OPS 1
typedef AO_t cairo_atomic_int_t;
# define _cairo_atomic_int_get(x) (AO_load_full (x))
# define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x))
# define _cairo_atomic_int_dec(x) ((void) AO_fetch_and_sub1_full(x))
# define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1)
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) AO_compare_and_swap_full(x, oldv, newv)
#if SIZEOF_VOID_P==SIZEOF_INT
typedef unsigned int cairo_atomic_intptr_t;
#elif SIZEOF_VOID_P==SIZEOF_LONG
typedef unsigned long cairo_atomic_intptr_t;
#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
typedef unsigned long long cairo_atomic_intptr_t;
#else
#error No matching integer pointer type
#endif
# define _cairo_atomic_ptr_get(x) _cairo_atomic_intptr_to_voidptr (AO_load_full (x))
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
_cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
#endif
#if HAVE_OS_ATOMIC_OPS
#include <libkern/OSAtomic.h>
#define HAS_ATOMIC_OPS 1
typedef int32_t cairo_atomic_int_t;
# define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
# define _cairo_atomic_int_inc(x) ((void) OSAtomicIncrement32Barrier (x))
# define _cairo_atomic_int_dec(x) ((void) OSAtomicDecrement32Barrier (x))
# define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0)
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) OSAtomicCompareAndSwap32Barrier(oldv, newv, x)
#if SIZEOF_VOID_P==4
typedef int32_t cairo_atomic_intptr_t;
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
OSAtomicCompareAndSwap32Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
#elif SIZEOF_VOID_P==8
typedef int64_t cairo_atomic_intptr_t;
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
OSAtomicCompareAndSwap64Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
#else
#error No matching integer pointer type
#endif
# define _cairo_atomic_ptr_get(x) (OSMemoryBarrier(), *(x))
#endif
#ifndef HAS_ATOMIC_OPS
#if SIZEOF_VOID_P==SIZEOF_INT
typedef unsigned int cairo_atomic_intptr_t;
#elif SIZEOF_VOID_P==SIZEOF_LONG
typedef unsigned long cairo_atomic_intptr_t;
#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
typedef unsigned long long cairo_atomic_intptr_t;
#else
#error No matching integer pointer type
#endif
typedef cairo_atomic_intptr_t cairo_atomic_int_t;
cairo_private void
_cairo_atomic_int_inc (cairo_atomic_int_t *x);
#define _cairo_atomic_int_dec(x) _cairo_atomic_int_dec_and_test(x)
cairo_private cairo_bool_t
_cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x);
cairo_private cairo_atomic_int_t
_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv);
cairo_private void *
_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_impl (x, oldv, newv)
#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_impl (x, oldv, newv)
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
cairo_private cairo_atomic_int_t
_cairo_atomic_int_get (cairo_atomic_int_t *x);
# define _cairo_atomic_ptr_get(x) (void *) _cairo_atomic_int_get((cairo_atomic_int_t *) x)
#else
# define _cairo_atomic_int_get(x) (*x)
# define _cairo_atomic_ptr_get(x) (*x)
#endif
#else
/* Workaround GCC complaining about casts */
static cairo_always_inline void *
_cairo_atomic_intptr_to_voidptr (cairo_atomic_intptr_t x)
{
return (void *) x;
}
static cairo_always_inline cairo_atomic_int_t
_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv)
{
cairo_atomic_int_t curr;
do {
curr = _cairo_atomic_int_get (x);
} while (curr == oldv && !_cairo_atomic_int_cmpxchg (x, oldv, newv));
return curr;
}
static cairo_always_inline void *
_cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
{
void *curr;
do {
curr = _cairo_atomic_ptr_get (x);
} while (curr == oldv && !_cairo_atomic_ptr_cmpxchg (x, oldv, newv));
return curr;
}
#endif
#ifndef _cairo_atomic_int_cmpxchg_return_old
#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_fallback (x, oldv, newv)
#endif
#ifndef _cairo_atomic_ptr_cmpxchg_return_old
#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_fallback (x, oldv, newv)
#endif
#ifndef _cairo_atomic_int_cmpxchg
#define _cairo_atomic_int_cmpxchg(x, oldv, newv) (_cairo_atomic_int_cmpxchg_return_old (x, oldv, newv) == oldv)
#endif
#ifndef _cairo_atomic_ptr_cmpxchg
#define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) (_cairo_atomic_ptr_cmpxchg_return_old (x, oldv, newv) == oldv)
#endif
#define _cairo_atomic_uint_get(x) _cairo_atomic_int_get(x)
#define _cairo_atomic_uint_cmpxchg(x, oldv, newv) \
_cairo_atomic_int_cmpxchg((cairo_atomic_int_t *)x, oldv, newv)
#define _cairo_status_set_error(status, err) do { \
int ret__; \
assert (err < CAIRO_STATUS_LAST_STATUS); \
/* hide compiler warnings about cairo_status_t != int (gcc treats its as \
* an unsigned integer instead, and about ignoring the return value. */ \
ret__ = _cairo_atomic_int_cmpxchg ((cairo_atomic_int_t *) status, CAIRO_STATUS_SUCCESS, err); \
(void) ret__; \
} while (0)
CAIRO_END_DECLS
#endif

View File

@@ -0,0 +1,106 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2007 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-atomic-private.h"
#include "cairo-mutex-private.h"
#ifdef HAS_ATOMIC_OPS
COMPILE_TIME_ASSERT(sizeof(void*) == sizeof(int) ||
sizeof(void*) == sizeof(long) ||
sizeof(void*) == sizeof(long long));
#else
void
_cairo_atomic_int_inc (cairo_atomic_intptr_t *x)
{
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
*x += 1;
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
}
cairo_bool_t
_cairo_atomic_int_dec_and_test (cairo_atomic_intptr_t *x)
{
cairo_bool_t ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = --*x == 0;
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
return ret;
}
cairo_atomic_intptr_t
_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, cairo_atomic_intptr_t oldv, cairo_atomic_intptr_t newv)
{
cairo_atomic_intptr_t ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = *x;
if (ret == oldv)
*x = newv;
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
return ret;
}
void *
_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv)
{
void *ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = *x;
if (ret == oldv)
*x = newv;
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
return ret;
}
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
cairo_atomic_intptr_t
_cairo_atomic_int_get (cairo_atomic_intptr_t *x)
{
cairo_atomic_intptr_t ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = *x;
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
return ret;
}
#endif
#endif

View File

@@ -0,0 +1,201 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2010 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Intel Corporation
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_BACKEND_PRIVATE_H
#define CAIRO_BACKEND_PRIVATE_H
#include "cairo-types-private.h"
#include "cairo-private.h"
typedef enum _cairo_backend_type {
CAIRO_TYPE_DEFAULT,
CAIRO_TYPE_SKIA,
} cairo_backend_type_t;
struct _cairo_backend {
cairo_backend_type_t type;
void (*destroy) (void *cr);
cairo_surface_t *(*get_original_target) (void *cr);
cairo_surface_t *(*get_current_target) (void *cr);
cairo_status_t (*save) (void *cr);
cairo_status_t (*restore) (void *cr);
cairo_status_t (*push_group) (void *cr, cairo_content_t content);
cairo_pattern_t *(*pop_group) (void *cr);
cairo_status_t (*set_source_rgba) (void *cr, double red, double green, double blue, double alpha);
cairo_status_t (*set_source_surface) (void *cr, cairo_surface_t *surface, double x, double y);
cairo_status_t (*set_source) (void *cr, cairo_pattern_t *source);
cairo_pattern_t *(*get_source) (void *cr);
cairo_status_t (*set_antialias) (void *cr, cairo_antialias_t antialias);
cairo_status_t (*set_dash) (void *cr, const double *dashes, int num_dashes, double offset);
cairo_status_t (*set_fill_rule) (void *cr, cairo_fill_rule_t fill_rule);
cairo_status_t (*set_line_cap) (void *cr, cairo_line_cap_t line_cap);
cairo_status_t (*set_line_join) (void *cr, cairo_line_join_t line_join);
cairo_status_t (*set_line_width) (void *cr, double line_width);
cairo_status_t (*set_miter_limit) (void *cr, double limit);
cairo_status_t (*set_opacity) (void *cr, double opacity);
cairo_status_t (*set_operator) (void *cr, cairo_operator_t op);
cairo_status_t (*set_tolerance) (void *cr, double tolerance);
cairo_antialias_t (*get_antialias) (void *cr);
void (*get_dash) (void *cr, double *dashes, int *num_dashes, double *offset);
cairo_fill_rule_t (*get_fill_rule) (void *cr);
cairo_line_cap_t (*get_line_cap) (void *cr);
cairo_line_join_t (*get_line_join) (void *cr);
double (*get_line_width) (void *cr);
double (*get_miter_limit) (void *cr);
double (*get_opacity) (void *cr);
cairo_operator_t (*get_operator) (void *cr);
double (*get_tolerance) (void *cr);
cairo_status_t (*translate) (void *cr, double tx, double ty);
cairo_status_t (*scale) (void *cr, double sx, double sy);
cairo_status_t (*rotate) (void *cr, double theta);
cairo_status_t (*transform) (void *cr, const cairo_matrix_t *matrix);
cairo_status_t (*set_matrix) (void *cr, const cairo_matrix_t *matrix);
cairo_status_t (*set_identity_matrix) (void *cr);
void (*get_matrix) (void *cr, cairo_matrix_t *matrix);
void (*user_to_device) (void *cr, double *x, double *y);
void (*user_to_device_distance) (void *cr, double *x, double *y);
void (*device_to_user) (void *cr, double *x, double *y);
void (*device_to_user_distance) (void *cr, double *x, double *y);
void (*user_to_backend) (void *cr, double *x, double *y);
void (*user_to_backend_distance) (void *cr, double *x, double *y);
void (*backend_to_user) (void *cr, double *x, double *y);
void (*backend_to_user_distance) (void *cr, double *x, double *y);
cairo_status_t (*new_path) (void *cr);
cairo_status_t (*new_sub_path) (void *cr);
cairo_status_t (*move_to) (void *cr, double x, double y);
cairo_status_t (*rel_move_to) (void *cr, double dx, double dy);
cairo_status_t (*line_to) (void *cr, double x, double y);
cairo_status_t (*rel_line_to) (void *cr, double dx, double dy);
cairo_status_t (*curve_to) (void *cr, double x1, double y1, double x2, double y2, double x3, double y3);
cairo_status_t (*rel_curve_to) (void *cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3);
cairo_status_t (*arc_to) (void *cr, double x1, double y1, double x2, double y2, double radius);
cairo_status_t (*rel_arc_to) (void *cr, double dx1, double dy1, double dx2, double dy2, double radius);
cairo_status_t (*close_path) (void *cr);
cairo_status_t (*arc) (void *cr, double xc, double yc, double radius, double angle1, double angle2, cairo_bool_t forward);
cairo_status_t (*rectangle) (void *cr, double x, double y, double width, double height);
void (*path_extents) (void *cr, double *x1, double *y1, double *x2, double *y2);
cairo_bool_t (*has_current_point) (void *cr);
cairo_bool_t (*get_current_point) (void *cr, double *x, double *y);
cairo_path_t *(*copy_path) (void *cr);
cairo_path_t *(*copy_path_flat) (void *cr);
cairo_status_t (*append_path) (void *cr, const cairo_path_t *path);
cairo_status_t (*stroke_to_path) (void *cr);
cairo_status_t (*clip) (void *cr);
cairo_status_t (*clip_preserve) (void *cr);
cairo_status_t (*in_clip) (void *cr, double x, double y, cairo_bool_t *inside);
cairo_status_t (*clip_extents) (void *cr, double *x1, double *y1, double *x2, double *y2);
cairo_status_t (*reset_clip) (void *cr);
cairo_rectangle_list_t *(*clip_copy_rectangle_list) (void *cr);
cairo_status_t (*paint) (void *cr);
cairo_status_t (*paint_with_alpha) (void *cr, double opacity);
cairo_status_t (*mask) (void *cr, cairo_pattern_t *pattern);
cairo_status_t (*stroke) (void *cr);
cairo_status_t (*stroke_preserve) (void *cr);
cairo_status_t (*in_stroke) (void *cr, double x, double y, cairo_bool_t *inside);
cairo_status_t (*stroke_extents) (void *cr, double *x1, double *y1, double *x2, double *y2);
cairo_status_t (*fill) (void *cr);
cairo_status_t (*fill_preserve) (void *cr);
cairo_status_t (*in_fill) (void *cr, double x, double y, cairo_bool_t *inside);
cairo_status_t (*fill_extents) (void *cr, double *x1, double *y1, double *x2, double *y2);
cairo_status_t (*set_font_face) (void *cr, cairo_font_face_t *font_face);
cairo_font_face_t *(*get_font_face) (void *cr);
cairo_status_t (*set_font_size) (void *cr, double size);
cairo_status_t (*set_font_matrix) (void *cr, const cairo_matrix_t *matrix);
void (*get_font_matrix) (void *cr, cairo_matrix_t *matrix);
cairo_status_t (*set_font_options) (void *cr, const cairo_font_options_t *options);
void (*get_font_options) (void *cr, cairo_font_options_t *options);
cairo_status_t (*set_scaled_font) (void *cr, cairo_scaled_font_t *scaled_font);
cairo_scaled_font_t *(*get_scaled_font) (void *cr);
cairo_status_t (*font_extents) (void *cr, cairo_font_extents_t *extents);
cairo_status_t (*glyphs) (void *cr,
const cairo_glyph_t *glyphs, int num_glyphs,
cairo_glyph_text_info_t *info);
cairo_status_t (*glyph_path) (void *cr,
const cairo_glyph_t *glyphs, int num_glyphs);
cairo_status_t (*glyph_extents) (void *cr,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_text_extents_t *extents);
cairo_status_t (*copy_page) (void *cr);
cairo_status_t (*show_page) (void *cr);
};
static inline void
_cairo_backend_to_user (cairo_t *cr, double *x, double *y)
{
cr->backend->backend_to_user (cr, x, y);
}
static inline void
_cairo_backend_to_user_distance (cairo_t *cr, double *x, double *y)
{
cr->backend->backend_to_user_distance (cr, x, y);
}
static inline void
_cairo_user_to_backend (cairo_t *cr, double *x, double *y)
{
cr->backend->user_to_backend (cr, x, y);
}
static inline void
_cairo_user_to_backend_distance (cairo_t *cr, double *x, double *y)
{
cr->backend->user_to_backend_distance (cr, x, y);
}
#endif /* CAIRO_BACKEND_PRIVATE_H */

View File

@@ -0,0 +1,144 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005-2007 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Author(s):
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-error-private.h"
#include "cairo-output-stream-private.h"
typedef struct _cairo_base64_stream {
cairo_output_stream_t base;
cairo_output_stream_t *output;
unsigned int in_mem;
unsigned int trailing;
unsigned char src[3];
} cairo_base64_stream_t;
static char const base64_table[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static cairo_status_t
_cairo_base64_stream_write (cairo_output_stream_t *base,
const unsigned char *data,
unsigned int length)
{
cairo_base64_stream_t * stream = (cairo_base64_stream_t *) base;
unsigned char *src = stream->src;
unsigned int i;
if (stream->in_mem + length < 3) {
for (i = 0; i < length; i++) {
src[i + stream->in_mem] = *data++;
}
stream->in_mem += length;
return CAIRO_STATUS_SUCCESS;
}
do {
unsigned char dst[4];
for (i = stream->in_mem; i < 3; i++) {
src[i] = *data++;
length--;
}
stream->in_mem = 0;
dst[0] = base64_table[src[0] >> 2];
dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6];
dst[3] = base64_table[src[2] & 0xfc >> 2];
/* Special case for the last missing bits */
switch (stream->trailing) {
case 2:
dst[2] = '=';
case 1:
dst[3] = '=';
default:
break;
}
_cairo_output_stream_write (stream->output, dst, 4);
} while (length >= 3);
for (i = 0; i < length; i++) {
src[i] = *data++;
}
stream->in_mem = length;
return _cairo_output_stream_get_status (stream->output);
}
static cairo_status_t
_cairo_base64_stream_close (cairo_output_stream_t *base)
{
cairo_base64_stream_t *stream = (cairo_base64_stream_t *) base;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
if (stream->in_mem > 0) {
memset (stream->src + stream->in_mem, 0, 3 - stream->in_mem);
stream->trailing = 3 - stream->in_mem;
stream->in_mem = 3;
status = _cairo_base64_stream_write (base, NULL, 0);
}
return status;
}
cairo_output_stream_t *
_cairo_base64_stream_create (cairo_output_stream_t *output)
{
cairo_base64_stream_t *stream;
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (cairo_base64_stream_t));
if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
_cairo_output_stream_init (&stream->base,
_cairo_base64_stream_write,
NULL,
_cairo_base64_stream_close);
stream->output = output;
stream->in_mem = 0;
stream->trailing = 0;
return &stream->base;
}

View File

@@ -0,0 +1,131 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Author(s):
* Kristian Høgsberg <krh@redhat.com>
*/
#include "cairoint.h"
#include "cairo-error-private.h"
#include "cairo-output-stream-private.h"
typedef struct _cairo_base85_stream {
cairo_output_stream_t base;
cairo_output_stream_t *output;
unsigned char four_tuple[4];
int pending;
} cairo_base85_stream_t;
static void
_expand_four_tuple_to_five (unsigned char four_tuple[4],
unsigned char five_tuple[5],
cairo_bool_t *all_zero)
{
uint32_t value;
int digit, i;
value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
if (all_zero)
*all_zero = TRUE;
for (i = 0; i < 5; i++) {
digit = value % 85;
if (digit != 0 && all_zero)
*all_zero = FALSE;
five_tuple[4-i] = digit + 33;
value = value / 85;
}
}
static cairo_status_t
_cairo_base85_stream_write (cairo_output_stream_t *base,
const unsigned char *data,
unsigned int length)
{
cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base;
const unsigned char *ptr = data;
unsigned char five_tuple[5];
cairo_bool_t is_zero;
while (length) {
stream->four_tuple[stream->pending++] = *ptr++;
length--;
if (stream->pending == 4) {
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, &is_zero);
if (is_zero)
_cairo_output_stream_write (stream->output, "z", 1);
else
_cairo_output_stream_write (stream->output, five_tuple, 5);
stream->pending = 0;
}
}
return _cairo_output_stream_get_status (stream->output);
}
static cairo_status_t
_cairo_base85_stream_close (cairo_output_stream_t *base)
{
cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base;
unsigned char five_tuple[5];
if (stream->pending) {
memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending);
_expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL);
_cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1);
}
return _cairo_output_stream_get_status (stream->output);
}
cairo_output_stream_t *
_cairo_base85_stream_create (cairo_output_stream_t *output)
{
cairo_base85_stream_t *stream;
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = malloc (sizeof (cairo_base85_stream_t));
if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
}
_cairo_output_stream_init (&stream->base,
_cairo_base85_stream_write,
NULL,
_cairo_base85_stream_close);
stream->output = output;
stream->pending = 0;
return &stream->base;
}

View File

@@ -0,0 +1,884 @@
/*
* Copyright © 2004 Carl Worth
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Carl Worth
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
/* Provide definitions for standalone compilation */
#include "cairoint.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
#include "cairo-combsort-inline.h"
#include "cairo-list-private.h"
#include "cairo-traps-private.h"
#include <setjmp.h>
typedef struct _rectangle rectangle_t;
typedef struct _edge edge_t;
struct _edge {
edge_t *next, *prev;
edge_t *right;
cairo_fixed_t x, top;
int dir;
};
struct _rectangle {
edge_t left, right;
int32_t top, bottom;
};
#define UNROLL3(x) x x x
/* the parent is always given by index/2 */
#define PQ_PARENT_INDEX(i) ((i) >> 1)
#define PQ_FIRST_ENTRY 1
/* left and right children are index * 2 and (index * 2) +1 respectively */
#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
typedef struct _sweep_line {
rectangle_t **rectangles;
rectangle_t **stop;
edge_t head, tail, *insert, *cursor;
int32_t current_y;
int32_t last_y;
int stop_size;
int32_t insert_x;
cairo_fill_rule_t fill_rule;
cairo_bool_t do_traps;
void *container;
jmp_buf unwind;
} sweep_line_t;
#define DEBUG_TRAPS 0
#if DEBUG_TRAPS
static void
dump_traps (cairo_traps_t *traps, const char *filename)
{
FILE *file;
int n;
if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
return;
file = fopen (filename, "a");
if (file != NULL) {
for (n = 0; n < traps->num_traps; n++) {
fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n",
traps->traps[n].top,
traps->traps[n].bottom,
traps->traps[n].left.p1.x,
traps->traps[n].left.p1.y,
traps->traps[n].left.p2.x,
traps->traps[n].left.p2.y,
traps->traps[n].right.p1.x,
traps->traps[n].right.p1.y,
traps->traps[n].right.p2.x,
traps->traps[n].right.p2.y);
}
fprintf (file, "\n");
fclose (file);
}
}
#else
#define dump_traps(traps, filename)
#endif
static inline int
rectangle_compare_start (const rectangle_t *a,
const rectangle_t *b)
{
return a->top - b->top;
}
static inline int
rectangle_compare_stop (const rectangle_t *a,
const rectangle_t *b)
{
return a->bottom - b->bottom;
}
static inline void
pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle)
{
rectangle_t **elements;
int i, parent;
elements = sweep->stop;
for (i = ++sweep->stop_size;
i != PQ_FIRST_ENTRY &&
rectangle_compare_stop (rectangle,
elements[parent = PQ_PARENT_INDEX (i)]) < 0;
i = parent)
{
elements[i] = elements[parent];
}
elements[i] = rectangle;
}
static inline void
rectangle_pop_stop (sweep_line_t *sweep)
{
rectangle_t **elements = sweep->stop;
rectangle_t *tail;
int child, i;
tail = elements[sweep->stop_size--];
if (sweep->stop_size == 0) {
elements[PQ_FIRST_ENTRY] = NULL;
return;
}
for (i = PQ_FIRST_ENTRY;
(child = PQ_LEFT_CHILD_INDEX (i)) <= sweep->stop_size;
i = child)
{
if (child != sweep->stop_size &&
rectangle_compare_stop (elements[child+1],
elements[child]) < 0)
{
child++;
}
if (rectangle_compare_stop (elements[child], tail) >= 0)
break;
elements[i] = elements[child];
}
elements[i] = tail;
}
static inline rectangle_t *
rectangle_pop_start (sweep_line_t *sweep_line)
{
return *sweep_line->rectangles++;
}
static inline rectangle_t *
rectangle_peek_stop (sweep_line_t *sweep_line)
{
return sweep_line->stop[PQ_FIRST_ENTRY];
}
CAIRO_COMBSORT_DECLARE (_rectangle_sort,
rectangle_t *,
rectangle_compare_start)
static void
sweep_line_init (sweep_line_t *sweep_line,
rectangle_t **rectangles,
int num_rectangles,
cairo_fill_rule_t fill_rule,
cairo_bool_t do_traps,
void *container)
{
rectangles[-2] = NULL;
rectangles[-1] = NULL;
rectangles[num_rectangles] = NULL;
sweep_line->rectangles = rectangles;
sweep_line->stop = rectangles - 2;
sweep_line->stop_size = 0;
sweep_line->insert = NULL;
sweep_line->insert_x = INT_MAX;
sweep_line->cursor = &sweep_line->tail;
sweep_line->head.dir = 0;
sweep_line->head.x = INT32_MIN;
sweep_line->head.right = NULL;
sweep_line->head.prev = NULL;
sweep_line->head.next = &sweep_line->tail;
sweep_line->tail.prev = &sweep_line->head;
sweep_line->tail.next = NULL;
sweep_line->tail.right = NULL;
sweep_line->tail.x = INT32_MAX;
sweep_line->tail.dir = 0;
sweep_line->current_y = INT32_MIN;
sweep_line->last_y = INT32_MIN;
sweep_line->fill_rule = fill_rule;
sweep_line->container = container;
sweep_line->do_traps = do_traps;
}
static void
edge_end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
/* Only emit (trivial) non-degenerate trapezoids with positive height. */
if (likely (left->top < bot)) {
if (sweep_line->do_traps) {
cairo_line_t _left = {
{ left->x, left->top },
{ left->x, bot },
}, _right = {
{ left->right->x, left->top },
{ left->right->x, bot },
};
_cairo_traps_add_trap (sweep_line->container, left->top, bot, &_left, &_right);
status = _cairo_traps_status ((cairo_traps_t *) sweep_line->container);
} else {
cairo_box_t box;
box.p1.x = left->x;
box.p1.y = left->top;
box.p2.x = left->right->x;
box.p2.y = bot;
status = _cairo_boxes_add (sweep_line->container,
CAIRO_ANTIALIAS_DEFAULT,
&box);
}
}
if (unlikely (status))
longjmp (sweep_line->unwind, status);
left->right = NULL;
}
/* Start a new trapezoid at the given top y coordinate, whose edges
* are `edge' and `edge->next'. If `edge' already has a trapezoid,
* then either add it to the traps in `traps', if the trapezoid's
* right edge differs from `edge->next', or do nothing if the new
* trapezoid would be a continuation of the existing one. */
static inline void
edge_start_or_continue_box (sweep_line_t *sweep_line,
edge_t *left,
edge_t *right,
int top)
{
if (left->right == right)
return;
if (left->right != NULL) {
if (left->right->x == right->x) {
/* continuation on right, so just swap edges */
left->right = right;
return;
}
edge_end_box (sweep_line, left, top);
}
if (left->x != right->x) {
left->top = top;
left->right = right;
}
}
/*
* Merge two sorted edge lists.
* Input:
* - head_a: The head of the first list.
* - head_b: The head of the second list; head_b cannot be NULL.
* Output:
* Returns the head of the merged list.
*
* Implementation notes:
* To make it fast (in particular, to reduce to an insertion sort whenever
* one of the two input lists only has a single element) we iterate through
* a list until its head becomes greater than the head of the other list,
* then we switch their roles. As soon as one of the two lists is empty, we
* just attach the other one to the current list and exit.
* Writes to memory are only needed to "switch" lists (as it also requires
* attaching to the output list the list which we will be iterating next) and
* to attach the last non-empty list.
*/
static edge_t *
merge_sorted_edges (edge_t *head_a, edge_t *head_b)
{
edge_t *head, *prev;
int32_t x;
prev = head_a->prev;
if (head_a->x <= head_b->x) {
head = head_a;
} else {
head_b->prev = prev;
head = head_b;
goto start_with_b;
}
do {
x = head_b->x;
while (head_a != NULL && head_a->x <= x) {
prev = head_a;
head_a = head_a->next;
}
head_b->prev = prev;
prev->next = head_b;
if (head_a == NULL)
return head;
start_with_b:
x = head_a->x;
while (head_b != NULL && head_b->x <= x) {
prev = head_b;
head_b = head_b->next;
}
head_a->prev = prev;
prev->next = head_a;
if (head_b == NULL)
return head;
} while (1);
}
/*
* Sort (part of) a list.
* Input:
* - list: The list to be sorted; list cannot be NULL.
* - limit: Recursion limit.
* Output:
* - head_out: The head of the sorted list containing the first 2^(level+1) elements of the
* input list; if the input list has fewer elements, head_out be a sorted list
* containing all the elements of the input list.
* Returns the head of the list of unprocessed elements (NULL if the sorted list contains
* all the elements of the input list).
*
* Implementation notes:
* Special case single element list, unroll/inline the sorting of the first two elements.
* Some tail recursion is used since we iterate on the bottom-up solution of the problem
* (we start with a small sorted list and keep merging other lists of the same size to it).
*/
static edge_t *
sort_edges (edge_t *list,
unsigned int level,
edge_t **head_out)
{
edge_t *head_other, *remaining;
unsigned int i;
head_other = list->next;
if (head_other == NULL) {
*head_out = list;
return NULL;
}
remaining = head_other->next;
if (list->x <= head_other->x) {
*head_out = list;
head_other->next = NULL;
} else {
*head_out = head_other;
head_other->prev = list->prev;
head_other->next = list;
list->prev = head_other;
list->next = NULL;
}
for (i = 0; i < level && remaining; i++) {
remaining = sort_edges (remaining, i, &head_other);
*head_out = merge_sorted_edges (*head_out, head_other);
}
return remaining;
}
static edge_t *
merge_unsorted_edges (edge_t *head, edge_t *unsorted)
{
sort_edges (unsorted, UINT_MAX, &unsorted);
return merge_sorted_edges (head, unsorted);
}
static void
active_edges_insert (sweep_line_t *sweep)
{
edge_t *prev;
int x;
x = sweep->insert_x;
prev = sweep->cursor;
if (prev->x > x) {
do {
prev = prev->prev;
} while (prev->x > x);
} else {
while (prev->next->x < x)
prev = prev->next;
}
prev->next = merge_unsorted_edges (prev->next, sweep->insert);
sweep->cursor = sweep->insert;
sweep->insert = NULL;
sweep->insert_x = INT_MAX;
}
static inline void
active_edges_to_traps (sweep_line_t *sweep)
{
int top = sweep->current_y;
edge_t *pos;
if (sweep->last_y == sweep->current_y)
return;
if (sweep->insert)
active_edges_insert (sweep);
pos = sweep->head.next;
if (pos == &sweep->tail)
return;
if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING) {
do {
edge_t *left, *right;
int winding;
left = pos;
winding = left->dir;
right = left->next;
/* Check if there is a co-linear edge with an existing trap */
while (right->x == left->x) {
if (right->right != NULL) {
assert (left->right == NULL);
/* continuation on left */
left->top = right->top;
left->right = right->right;
right->right = NULL;
}
winding += right->dir;
right = right->next;
}
if (winding == 0) {
if (left->right != NULL)
edge_end_box (sweep, left, top);
pos = right;
continue;
}
do {
/* End all subsumed traps */
if (unlikely (right->right != NULL))
edge_end_box (sweep, right, top);
/* Greedily search for the closing edge, so that we generate
* the * maximal span width with the minimal number of
* boxes.
*/
winding += right->dir;
if (winding == 0 && right->x != right->next->x)
break;
right = right->next;
} while (TRUE);
edge_start_or_continue_box (sweep, left, right, top);
pos = right->next;
} while (pos != &sweep->tail);
} else {
do {
edge_t *right = pos->next;
int count = 0;
do {
/* End all subsumed traps */
if (unlikely (right->right != NULL))
edge_end_box (sweep, right, top);
/* skip co-linear edges */
if (++count & 1 && right->x != right->next->x)
break;
right = right->next;
} while (TRUE);
edge_start_or_continue_box (sweep, pos, right, top);
pos = right->next;
} while (pos != &sweep->tail);
}
sweep->last_y = sweep->current_y;
}
static inline void
sweep_line_delete_edge (sweep_line_t *sweep, edge_t *edge)
{
if (edge->right != NULL) {
edge_t *next = edge->next;
if (next->x == edge->x) {
next->top = edge->top;
next->right = edge->right;
} else
edge_end_box (sweep, edge, sweep->current_y);
}
if (sweep->cursor == edge)
sweep->cursor = edge->prev;
edge->prev->next = edge->next;
edge->next->prev = edge->prev;
}
static inline cairo_bool_t
sweep_line_delete (sweep_line_t *sweep, rectangle_t *rectangle)
{
cairo_bool_t update;
update = TRUE;
if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING &&
rectangle->left.prev->dir == rectangle->left.dir)
{
update = rectangle->left.next != &rectangle->right;
}
sweep_line_delete_edge (sweep, &rectangle->left);
sweep_line_delete_edge (sweep, &rectangle->right);
rectangle_pop_stop (sweep);
return update;
}
static inline void
sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle)
{
if (sweep->insert)
sweep->insert->prev = &rectangle->right;
rectangle->right.next = sweep->insert;
rectangle->right.prev = &rectangle->left;
rectangle->left.next = &rectangle->right;
rectangle->left.prev = NULL;
sweep->insert = &rectangle->left;
if (rectangle->left.x < sweep->insert_x)
sweep->insert_x = rectangle->left.x;
pqueue_push (sweep, rectangle);
}
static cairo_status_t
_cairo_bentley_ottmann_tessellate_rectangular (rectangle_t **rectangles,
int num_rectangles,
cairo_fill_rule_t fill_rule,
cairo_bool_t do_traps,
void *container)
{
sweep_line_t sweep_line;
rectangle_t *rectangle;
cairo_status_t status;
cairo_bool_t update = FALSE;
sweep_line_init (&sweep_line,
rectangles, num_rectangles,
fill_rule,
do_traps, container);
if ((status = setjmp (sweep_line.unwind)))
return status;
rectangle = rectangle_pop_start (&sweep_line);
do {
if (rectangle->top != sweep_line.current_y) {
rectangle_t *stop;
stop = rectangle_peek_stop (&sweep_line);
while (stop != NULL && stop->bottom < rectangle->top) {
if (stop->bottom != sweep_line.current_y) {
if (update) {
active_edges_to_traps (&sweep_line);
update = FALSE;
}
sweep_line.current_y = stop->bottom;
}
update |= sweep_line_delete (&sweep_line, stop);
stop = rectangle_peek_stop (&sweep_line);
}
if (update) {
active_edges_to_traps (&sweep_line);
update = FALSE;
}
sweep_line.current_y = rectangle->top;
}
do {
sweep_line_insert (&sweep_line, rectangle);
} while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL &&
sweep_line.current_y == rectangle->top);
update = TRUE;
} while (rectangle);
while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) {
if (rectangle->bottom != sweep_line.current_y) {
if (update) {
active_edges_to_traps (&sweep_line);
update = FALSE;
}
sweep_line.current_y = rectangle->bottom;
}
update |= sweep_line_delete (&sweep_line, rectangle);
}
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_bentley_ottmann_tessellate_rectangular_traps (cairo_traps_t *traps,
cairo_fill_rule_t fill_rule)
{
rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 3];
rectangle_t *rectangles, **rectangles_ptrs;
cairo_status_t status;
int i;
if (unlikely (traps->num_traps <= 1))
return CAIRO_STATUS_SUCCESS;
assert (traps->is_rectangular);
dump_traps (traps, "bo-rects-traps-in.txt");
rectangles = stack_rectangles;
rectangles_ptrs = stack_rectangles_ptrs;
if (traps->num_traps > ARRAY_LENGTH (stack_rectangles)) {
rectangles = _cairo_malloc_ab_plus_c (traps->num_traps,
sizeof (rectangle_t) +
sizeof (rectangle_t *),
3*sizeof (rectangle_t *));
if (unlikely (rectangles == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
rectangles_ptrs = (rectangle_t **) (rectangles + traps->num_traps);
}
for (i = 0; i < traps->num_traps; i++) {
if (traps->traps[i].left.p1.x < traps->traps[i].right.p1.x) {
rectangles[i].left.x = traps->traps[i].left.p1.x;
rectangles[i].left.dir = 1;
rectangles[i].right.x = traps->traps[i].right.p1.x;
rectangles[i].right.dir = -1;
} else {
rectangles[i].right.x = traps->traps[i].left.p1.x;
rectangles[i].right.dir = 1;
rectangles[i].left.x = traps->traps[i].right.p1.x;
rectangles[i].left.dir = -1;
}
rectangles[i].left.right = NULL;
rectangles[i].right.right = NULL;
rectangles[i].top = traps->traps[i].top;
rectangles[i].bottom = traps->traps[i].bottom;
rectangles_ptrs[i+2] = &rectangles[i];
}
/* XXX incremental sort */
_rectangle_sort (rectangles_ptrs+2, i);
_cairo_traps_clear (traps);
status = _cairo_bentley_ottmann_tessellate_rectangular (rectangles_ptrs+2, i,
fill_rule,
TRUE, traps);
traps->is_rectilinear = TRUE;
traps->is_rectangular = TRUE;
if (rectangles != stack_rectangles)
free (rectangles);
dump_traps (traps, "bo-rects-traps-out.txt");
return status;
}
cairo_status_t
_cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in,
cairo_fill_rule_t fill_rule,
cairo_boxes_t *out)
{
rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 3];
rectangle_t *rectangles, **rectangles_ptrs;
rectangle_t *stack_rectangles_chain[CAIRO_STACK_ARRAY_LENGTH (rectangle_t *) ];
rectangle_t **rectangles_chain = NULL;
const struct _cairo_boxes_chunk *chunk;
cairo_status_t status;
int i, j, y_min, y_max;
if (unlikely (in->num_boxes == 0)) {
_cairo_boxes_clear (out);
return CAIRO_STATUS_SUCCESS;
}
if (in->num_boxes == 1) {
if (in == out) {
cairo_box_t *box = &in->chunks.base[0];
if (box->p1.x > box->p2.x) {
cairo_fixed_t tmp = box->p1.x;
box->p1.x = box->p2.x;
box->p2.x = tmp;
}
} else {
cairo_box_t box = in->chunks.base[0];
if (box.p1.x > box.p2.x) {
cairo_fixed_t tmp = box.p1.x;
box.p1.x = box.p2.x;
box.p2.x = tmp;
}
_cairo_boxes_clear (out);
status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
assert (status == CAIRO_STATUS_SUCCESS);
}
return CAIRO_STATUS_SUCCESS;
}
y_min = INT_MAX; y_max = INT_MIN;
for (chunk = &in->chunks; chunk != NULL; chunk = chunk->next) {
const cairo_box_t *box = chunk->base;
for (i = 0; i < chunk->count; i++) {
if (box[i].p1.y < y_min)
y_min = box[i].p1.y;
if (box[i].p1.y > y_max)
y_max = box[i].p1.y;
}
}
y_min = _cairo_fixed_integer_floor (y_min);
y_max = _cairo_fixed_integer_floor (y_max) + 1;
y_max -= y_min;
if (y_max < in->num_boxes) {
rectangles_chain = stack_rectangles_chain;
if (y_max > ARRAY_LENGTH (stack_rectangles_chain)) {
rectangles_chain = _cairo_malloc_ab (y_max, sizeof (rectangle_t *));
if (unlikely (rectangles_chain == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
memset (rectangles_chain, 0, y_max * sizeof (rectangle_t*));
}
rectangles = stack_rectangles;
rectangles_ptrs = stack_rectangles_ptrs;
if (in->num_boxes > ARRAY_LENGTH (stack_rectangles)) {
rectangles = _cairo_malloc_ab_plus_c (in->num_boxes,
sizeof (rectangle_t) +
sizeof (rectangle_t *),
3*sizeof (rectangle_t *));
if (unlikely (rectangles == NULL)) {
if (rectangles_chain != stack_rectangles_chain)
free (rectangles_chain);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
rectangles_ptrs = (rectangle_t **) (rectangles + in->num_boxes);
}
j = 0;
for (chunk = &in->chunks; chunk != NULL; chunk = chunk->next) {
const cairo_box_t *box = chunk->base;
for (i = 0; i < chunk->count; i++) {
int h;
if (box[i].p1.x < box[i].p2.x) {
rectangles[j].left.x = box[i].p1.x;
rectangles[j].left.dir = 1;
rectangles[j].right.x = box[i].p2.x;
rectangles[j].right.dir = -1;
} else {
rectangles[j].right.x = box[i].p1.x;
rectangles[j].right.dir = 1;
rectangles[j].left.x = box[i].p2.x;
rectangles[j].left.dir = -1;
}
rectangles[j].left.right = NULL;
rectangles[j].right.right = NULL;
rectangles[j].top = box[i].p1.y;
rectangles[j].bottom = box[i].p2.y;
if (rectangles_chain) {
h = _cairo_fixed_integer_floor (box[i].p1.y) - y_min;
rectangles[j].left.next = (edge_t *)rectangles_chain[h];
rectangles_chain[h] = &rectangles[j];
} else {
rectangles_ptrs[j+2] = &rectangles[j];
}
j++;
}
}
if (rectangles_chain) {
j = 2;
for (y_min = 0; y_min < y_max; y_min++) {
rectangle_t *r;
int start = j;
for (r = rectangles_chain[y_min]; r; r = (rectangle_t *)r->left.next)
rectangles_ptrs[j++] = r;
if (j > start + 1)
_rectangle_sort (rectangles_ptrs + start, j - start);
}
if (rectangles_chain != stack_rectangles_chain)
free (rectangles_chain);
j -= 2;
} else {
_rectangle_sort (rectangles_ptrs + 2, j);
}
_cairo_boxes_clear (out);
status = _cairo_bentley_ottmann_tessellate_rectangular (rectangles_ptrs+2, j,
fill_rule,
FALSE, out);
if (rectangles != stack_rectangles)
free (rectangles);
return status;
}

View File

@@ -0,0 +1,600 @@
/*
* Copyright © 2004 Carl Worth
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2008 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Carl Worth
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
/* Provide definitions for standalone compilation */
#include "cairoint.h"
#include "cairo-boxes-private.h"
#include "cairo-combsort-inline.h"
#include "cairo-error-private.h"
#include "cairo-traps-private.h"
typedef struct _cairo_bo_edge cairo_bo_edge_t;
typedef struct _cairo_bo_trap cairo_bo_trap_t;
/* A deferred trapezoid of an edge */
struct _cairo_bo_trap {
cairo_bo_edge_t *right;
int32_t top;
};
struct _cairo_bo_edge {
cairo_edge_t edge;
cairo_bo_edge_t *prev;
cairo_bo_edge_t *next;
cairo_bo_trap_t deferred_trap;
};
typedef enum {
CAIRO_BO_EVENT_TYPE_START,
CAIRO_BO_EVENT_TYPE_STOP
} cairo_bo_event_type_t;
typedef struct _cairo_bo_event {
cairo_bo_event_type_t type;
cairo_point_t point;
cairo_bo_edge_t *edge;
} cairo_bo_event_t;
typedef struct _cairo_bo_sweep_line {
cairo_bo_event_t **events;
cairo_bo_edge_t *head;
cairo_bo_edge_t *stopped;
int32_t current_y;
cairo_bo_edge_t *current_edge;
} cairo_bo_sweep_line_t;
static inline int
_cairo_point_compare (const cairo_point_t *a,
const cairo_point_t *b)
{
int cmp;
cmp = a->y - b->y;
if (likely (cmp))
return cmp;
return a->x - b->x;
}
static inline int
_cairo_bo_edge_compare (const cairo_bo_edge_t *a,
const cairo_bo_edge_t *b)
{
int cmp;
cmp = a->edge.line.p1.x - b->edge.line.p1.x;
if (likely (cmp))
return cmp;
return b->edge.bottom - a->edge.bottom;
}
static inline int
cairo_bo_event_compare (const cairo_bo_event_t *a,
const cairo_bo_event_t *b)
{
int cmp;
cmp = _cairo_point_compare (&a->point, &b->point);
if (likely (cmp))
return cmp;
cmp = a->type - b->type;
if (cmp)
return cmp;
return a - b;
}
static inline cairo_bo_event_t *
_cairo_bo_event_dequeue (cairo_bo_sweep_line_t *sweep_line)
{
return *sweep_line->events++;
}
CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort,
cairo_bo_event_t *,
cairo_bo_event_compare)
static void
_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line,
cairo_bo_event_t **events,
int num_events)
{
_cairo_bo_event_queue_sort (events, num_events);
events[num_events] = NULL;
sweep_line->events = events;
sweep_line->head = NULL;
sweep_line->current_y = INT32_MIN;
sweep_line->current_edge = NULL;
}
static void
_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line,
cairo_bo_edge_t *edge)
{
if (sweep_line->current_edge != NULL) {
cairo_bo_edge_t *prev, *next;
int cmp;
cmp = _cairo_bo_edge_compare (sweep_line->current_edge, edge);
if (cmp < 0) {
prev = sweep_line->current_edge;
next = prev->next;
while (next != NULL && _cairo_bo_edge_compare (next, edge) < 0)
prev = next, next = prev->next;
prev->next = edge;
edge->prev = prev;
edge->next = next;
if (next != NULL)
next->prev = edge;
} else if (cmp > 0) {
next = sweep_line->current_edge;
prev = next->prev;
while (prev != NULL && _cairo_bo_edge_compare (prev, edge) > 0)
next = prev, prev = next->prev;
next->prev = edge;
edge->next = next;
edge->prev = prev;
if (prev != NULL)
prev->next = edge;
else
sweep_line->head = edge;
} else {
prev = sweep_line->current_edge;
edge->prev = prev;
edge->next = prev->next;
if (prev->next != NULL)
prev->next->prev = edge;
prev->next = edge;
}
} else {
sweep_line->head = edge;
}
sweep_line->current_edge = edge;
}
static void
_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line,
cairo_bo_edge_t *edge)
{
if (edge->prev != NULL)
edge->prev->next = edge->next;
else
sweep_line->head = edge->next;
if (edge->next != NULL)
edge->next->prev = edge->prev;
if (sweep_line->current_edge == edge)
sweep_line->current_edge = edge->prev ? edge->prev : edge->next;
}
static inline cairo_bool_t
edges_collinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b)
{
return a->edge.line.p1.x == b->edge.line.p1.x;
}
static cairo_status_t
_cairo_bo_edge_end_trap (cairo_bo_edge_t *left,
int32_t bot,
cairo_bool_t do_traps,
void *container)
{
cairo_bo_trap_t *trap = &left->deferred_trap;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
/* Only emit (trivial) non-degenerate trapezoids with positive height. */
if (likely (trap->top < bot)) {
if (do_traps) {
_cairo_traps_add_trap (container,
trap->top, bot,
&left->edge.line, &trap->right->edge.line);
status = _cairo_traps_status ((cairo_traps_t *) container);
} else {
cairo_box_t box;
box.p1.x = left->edge.line.p1.x;
box.p1.y = trap->top;
box.p2.x = trap->right->edge.line.p1.x;
box.p2.y = bot;
status = _cairo_boxes_add (container, CAIRO_ANTIALIAS_DEFAULT, &box);
}
}
trap->right = NULL;
return status;
}
/* Start a new trapezoid at the given top y coordinate, whose edges
* are `edge' and `edge->next'. If `edge' already has a trapezoid,
* then either add it to the traps in `traps', if the trapezoid's
* right edge differs from `edge->next', or do nothing if the new
* trapezoid would be a continuation of the existing one. */
static inline cairo_status_t
_cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t *left,
cairo_bo_edge_t *right,
int top,
cairo_bool_t do_traps,
void *container)
{
cairo_status_t status;
if (left->deferred_trap.right == right)
return CAIRO_STATUS_SUCCESS;
if (left->deferred_trap.right != NULL) {
if (right != NULL && edges_collinear (left->deferred_trap.right, right))
{
/* continuation on right, so just swap edges */
left->deferred_trap.right = right;
return CAIRO_STATUS_SUCCESS;
}
status = _cairo_bo_edge_end_trap (left, top, do_traps, container);
if (unlikely (status))
return status;
}
if (right != NULL && ! edges_collinear (left, right)) {
left->deferred_trap.top = top;
left->deferred_trap.right = right;
}
return CAIRO_STATUS_SUCCESS;
}
static inline cairo_status_t
_active_edges_to_traps (cairo_bo_edge_t *left,
int32_t top,
cairo_fill_rule_t fill_rule,
cairo_bool_t do_traps,
void *container)
{
cairo_bo_edge_t *right;
cairo_status_t status;
if (fill_rule == CAIRO_FILL_RULE_WINDING) {
while (left != NULL) {
int in_out;
/* Greedily search for the closing edge, so that we generate the
* maximal span width with the minimal number of trapezoids.
*/
in_out = left->edge.dir;
/* Check if there is a co-linear edge with an existing trap */
right = left->next;
if (left->deferred_trap.right == NULL) {
while (right != NULL && right->deferred_trap.right == NULL)
right = right->next;
if (right != NULL && edges_collinear (left, right)) {
/* continuation on left */
left->deferred_trap = right->deferred_trap;
right->deferred_trap.right = NULL;
}
}
/* End all subsumed traps */
right = left->next;
while (right != NULL) {
if (right->deferred_trap.right != NULL) {
status = _cairo_bo_edge_end_trap (right, top, do_traps, container);
if (unlikely (status))
return status;
}
in_out += right->edge.dir;
if (in_out == 0) {
/* skip co-linear edges */
if (right->next == NULL ||
! edges_collinear (right, right->next))
{
break;
}
}
right = right->next;
}
status = _cairo_bo_edge_start_or_continue_trap (left, right, top,
do_traps, container);
if (unlikely (status))
return status;
left = right;
if (left != NULL)
left = left->next;
}
} else {
while (left != NULL) {
int in_out = 0;
right = left->next;
while (right != NULL) {
if (right->deferred_trap.right != NULL) {
status = _cairo_bo_edge_end_trap (right, top, do_traps, container);
if (unlikely (status))
return status;
}
if ((in_out++ & 1) == 0) {
cairo_bo_edge_t *next;
cairo_bool_t skip = FALSE;
/* skip co-linear edges */
next = right->next;
if (next != NULL)
skip = edges_collinear (right, next);
if (! skip)
break;
}
right = right->next;
}
status = _cairo_bo_edge_start_or_continue_trap (left, right, top,
do_traps, container);
if (unlikely (status))
return status;
left = right;
if (left != NULL)
left = left->next;
}
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_bentley_ottmann_tessellate_rectilinear (cairo_bo_event_t **start_events,
int num_events,
cairo_fill_rule_t fill_rule,
cairo_bool_t do_traps,
void *container)
{
cairo_bo_sweep_line_t sweep_line;
cairo_bo_event_t *event;
cairo_status_t status;
_cairo_bo_sweep_line_init (&sweep_line, start_events, num_events);
while ((event = _cairo_bo_event_dequeue (&sweep_line))) {
if (event->point.y != sweep_line.current_y) {
status = _active_edges_to_traps (sweep_line.head,
sweep_line.current_y,
fill_rule, do_traps, container);
if (unlikely (status))
return status;
sweep_line.current_y = event->point.y;
}
switch (event->type) {
case CAIRO_BO_EVENT_TYPE_START:
_cairo_bo_sweep_line_insert (&sweep_line, event->edge);
break;
case CAIRO_BO_EVENT_TYPE_STOP:
_cairo_bo_sweep_line_delete (&sweep_line, event->edge);
if (event->edge->deferred_trap.right != NULL) {
status = _cairo_bo_edge_end_trap (event->edge,
sweep_line.current_y,
do_traps, container);
if (unlikely (status))
return status;
}
break;
}
}
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (const cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule,
cairo_boxes_t *boxes)
{
cairo_status_t status;
cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)];
cairo_bo_event_t *events;
cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
cairo_bo_event_t **event_ptrs;
cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)];
cairo_bo_edge_t *edges;
int num_events;
int i, j;
if (unlikely (polygon->num_edges == 0))
return CAIRO_STATUS_SUCCESS;
num_events = 2 * polygon->num_edges;
events = stack_events;
event_ptrs = stack_event_ptrs;
edges = stack_edges;
if (num_events > ARRAY_LENGTH (stack_events)) {
events = _cairo_malloc_ab_plus_c (num_events,
sizeof (cairo_bo_event_t) +
sizeof (cairo_bo_edge_t) +
sizeof (cairo_bo_event_t *),
sizeof (cairo_bo_event_t *));
if (unlikely (events == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
event_ptrs = (cairo_bo_event_t **) (events + num_events);
edges = (cairo_bo_edge_t *) (event_ptrs + num_events + 1);
}
for (i = j = 0; i < polygon->num_edges; i++) {
edges[i].edge = polygon->edges[i];
edges[i].deferred_trap.right = NULL;
edges[i].prev = NULL;
edges[i].next = NULL;
event_ptrs[j] = &events[j];
events[j].type = CAIRO_BO_EVENT_TYPE_START;
events[j].point.y = polygon->edges[i].top;
events[j].point.x = polygon->edges[i].line.p1.x;
events[j].edge = &edges[i];
j++;
event_ptrs[j] = &events[j];
events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
events[j].point.y = polygon->edges[i].bottom;
events[j].point.x = polygon->edges[i].line.p1.x;
events[j].edge = &edges[i];
j++;
}
status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
fill_rule,
FALSE, boxes);
if (events != stack_events)
free (events);
return status;
}
cairo_status_t
_cairo_bentley_ottmann_tessellate_rectilinear_traps (cairo_traps_t *traps,
cairo_fill_rule_t fill_rule)
{
cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)];
cairo_bo_event_t *events;
cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
cairo_bo_event_t **event_ptrs;
cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)];
cairo_bo_edge_t *edges;
cairo_status_t status;
int i, j, k;
if (unlikely (traps->num_traps == 0))
return CAIRO_STATUS_SUCCESS;
assert (traps->is_rectilinear);
i = 4 * traps->num_traps;
events = stack_events;
event_ptrs = stack_event_ptrs;
edges = stack_edges;
if (i > ARRAY_LENGTH (stack_events)) {
events = _cairo_malloc_ab_plus_c (i,
sizeof (cairo_bo_event_t) +
sizeof (cairo_bo_edge_t) +
sizeof (cairo_bo_event_t *),
sizeof (cairo_bo_event_t *));
if (unlikely (events == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
event_ptrs = (cairo_bo_event_t **) (events + i);
edges = (cairo_bo_edge_t *) (event_ptrs + i + 1);
}
for (i = j = k = 0; i < traps->num_traps; i++) {
edges[k].edge.top = traps->traps[i].top;
edges[k].edge.bottom = traps->traps[i].bottom;
edges[k].edge.line = traps->traps[i].left;
edges[k].edge.dir = 1;
edges[k].deferred_trap.right = NULL;
edges[k].prev = NULL;
edges[k].next = NULL;
event_ptrs[j] = &events[j];
events[j].type = CAIRO_BO_EVENT_TYPE_START;
events[j].point.y = traps->traps[i].top;
events[j].point.x = traps->traps[i].left.p1.x;
events[j].edge = &edges[k];
j++;
event_ptrs[j] = &events[j];
events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
events[j].point.y = traps->traps[i].bottom;
events[j].point.x = traps->traps[i].left.p1.x;
events[j].edge = &edges[k];
j++;
k++;
edges[k].edge.top = traps->traps[i].top;
edges[k].edge.bottom = traps->traps[i].bottom;
edges[k].edge.line = traps->traps[i].right;
edges[k].edge.dir = -1;
edges[k].deferred_trap.right = NULL;
edges[k].prev = NULL;
edges[k].next = NULL;
event_ptrs[j] = &events[j];
events[j].type = CAIRO_BO_EVENT_TYPE_START;
events[j].point.y = traps->traps[i].top;
events[j].point.x = traps->traps[i].right.p1.x;
events[j].edge = &edges[k];
j++;
event_ptrs[j] = &events[j];
events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
events[j].point.y = traps->traps[i].bottom;
events[j].point.x = traps->traps[i].right.p1.x;
events[j].edge = &edges[k];
j++;
k++;
}
_cairo_traps_clear (traps);
status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
fill_rule,
TRUE, traps);
traps->is_rectilinear = TRUE;
if (events != stack_events)
free (events);
return status;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,984 @@
/* vim:set ts=8 sw=4 noet cin: */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Christian Biesinger <cbiesinger@web.de>
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Christian Biesinger
* <cbiesinger@web.de>
*
* Contributor(s):
*/
// This is a C++ file in order to use the C++ BeOS API
#include "cairoint.h"
#include "cairo-beos.h"
#include "cairo-error-private.h"
#include "cairo-image-surface-inline.h"
#include <new>
#include <Bitmap.h>
#include <Region.h>
#if 0
#include <DirectWindow.h>
#endif
#include <Screen.h>
#include <Window.h>
#include <Locker.h>
/**
* SECTION:beos-surface
* @Title: BeOS Surfaces
* @Short_Description: BeOS surface support
* @See_Also: #cairo_surface_t
*
* The BeOS surface is used to render cairo graphics to BeOS views
* and bitmaps.
**/
#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS)
struct cairo_beos_surface_t {
cairo_surface_t base;
cairo_region_t *clip_region;
BView* view;
/*
* A view is either attached to a bitmap, a window, or unattached.
* If it is attached to a window, we can copy data out of it using BScreen.
* If it is attached to a bitmap, we can read the bitmap data.
* If it is not attached, it doesn't draw anything, we need not bother.
*
* Since there doesn't seem to be a way to get the bitmap from a view if it
* is attached to one, we have to use a special surface creation function.
*/
BBitmap* bitmap;
// If true, surface and view should be deleted when this surface is
// destroyed
bool owns_bitmap_view;
};
class AutoLockView {
public:
AutoLockView(BView* view) : mView(view) {
mOK = mView->LockLooper();
}
~AutoLockView() {
if (mOK)
mView->UnlockLooper();
}
operator bool() {
return mOK;
}
private:
BView* mView;
bool mOK;
};
static cairo_surface_t *
_cairo_beos_surface_create_internal (BView* view,
BBitmap* bmp,
bool owns_bitmap_view = false);
static inline BRect
_cairo_rectangle_to_brect (const cairo_rectangle_int_t* rect)
{
// A BRect is one pixel wider than you'd think
return BRect (rect->x, rect->y,
rect->x + rect->width - 1,
rect->y + rect->height - 1);
}
static inline cairo_rectangle_int_t
_brect_to_cairo_rectangle (const BRect &rect)
{
cairo_rectangle_int_t retval;
retval.x = floor (rect.left);
retval.y = floor (rect.top);
retval.width = ceil (rect.right) - retval.x + 1;
retval.height = ceil (rect.bottom) - rectval.y + 1;
return retval;
}
static inline rgb_color
_cairo_color_to_be_color (const cairo_color_t *color)
{
// This factor ensures a uniform distribution of numbers
const float factor = 256 - 1e-5;
// Using doubles to have non-premultiplied colors
rgb_color be_color = { uint8(color->red * factor),
uint8(color->green * factor),
uint8(color->blue * factor),
uint8(color->alpha * factor) };
return be_color;
}
enum ViewCopyStatus {
OK,
NOT_VISIBLE, // The view or the interest rect is not visible on screen
ERROR // The view was visible, but the rect could not be copied. Probably OOM
};
/**
* _cairo_beos_view_to_bitmap:
* @bitmap: [out] The resulting bitmap.
* @rect: [out] The rectangle that was copied, in the view's coordinate system
* @interestRect: If non-null, only this part of the view will be copied (view's coord system).
*
* Gets the contents of the view as a BBitmap*. Caller must delete the bitmap.
**/
static ViewCopyStatus
_cairo_beos_view_to_bitmap (BView* view,
BBitmap** bitmap,
BRect* rect = NULL,
const BRect* interestRect = NULL)
{
*bitmap = NULL;
BWindow* wnd = view->Window();
// If we have no window, can't do anything
if (!wnd)
return NOT_VISIBLE;
view->Sync();
wnd->Sync();
#if 0
// Is it a direct window?
BDirectWindow* directWnd = dynamic_cast<BDirectWindow*>(wnd);
if (directWnd) {
// WRITEME
}
#endif
// Is it visible? If so, we can copy the content off the screen
if (wnd->IsHidden())
return NOT_VISIBLE;
BRect rectToCopy(view->Bounds());
if (interestRect)
rectToCopy = rectToCopy & *interestRect;
if (!rectToCopy.IsValid())
return NOT_VISIBLE;
BScreen screen(wnd);
BRect screenRect(view->ConvertToScreen(rectToCopy));
screenRect = screenRect & screen.Frame();
if (!screen.IsValid())
return NOT_VISIBLE;
if (rect)
*rect = view->ConvertFromScreen(screenRect);
if (screen.GetBitmap(bitmap, false, &screenRect) == B_OK)
return OK;
return ERROR;
}
static void
unpremultiply_bgra (unsigned char* data,
int width,
int height,
int stride,
unsigned char* retdata)
{
unsigned char* end = data + stride * height;
for (unsigned char* in = data, *out = retdata;
in < end;
in += stride, out += stride)
{
for (int i = 0; i < width; i ++) {
uint8_t *b = &out[4*i];
uint32_t pixel;
uint8_t alpha;
memcpy (&pixel, &data[4*i], sizeof (uint32_t));
alpha = pixel & 0xff;
if (alpha == 0) {
b[0] = b[1] = b[2] = b[3] = 0;
} else {
b[0] = (((pixel >> 24) & 0xff) * 255 + alpha / 2) / alpha;
b[1] = (((pixel >> 16) & 0xff) * 255 + alpha / 2) / alpha;
b[2] = (((pixel >> 8) & 0xff) * 255 + alpha / 2) / alpha;
b[3] = alpha;
}
}
}
}
static inline int
multiply_alpha (int alpha, int color)
{
int temp = (alpha * color) + 0x80;
return ((temp + (temp >> 8)) >> 8);
}
static unsigned char*
premultiply_bgra (unsigned char* data,
int width,
int height,
int stride)
{
uint8_t * retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
if (!retdata)
return NULL;
uint8_t * end = data + stride * height;
for (uint8_t * in = data, *out = retdata;
in < end;
in += stride, out += stride)
{
for (int i = 0; i < width; i ++) {
uint8_t *base = &in[4*i];
uint8_t alpha = base[3];
uint32_t p;
if (alpha == 0) {
p = 0;
} else {
uint8_t blue = base[0];
uint8_t green = base[1];
uint8_t red = base[2];
if (alpha != 0xff) {
blue = multiply_alpha (alpha, blue);
green = multiply_alpha (alpha, green);
red = multiply_alpha (alpha, red);
}
p = (alpha << 0) | (red << 8) | (green << 16) | (blue << 24);
}
memcpy (&out[4*i], &p, sizeof (uint32_t));
}
}
return retdata;
}
static cairo_int_status_t
_cairo_beos_surface_set_clip_region (cairo_beos_surface_t *surface,
cairo_region_t *region)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
AutoLockView locker(surface->view);
assert (locker);
if (region == surface->clip_region)
return CAIRO_INT_STATUS_SUCCESS;
cairo_region_destroy (surface->clip_region);
surface->clip_region = cairo_region_reference (region);
if (region == NULL) {
// No clipping
surface->view->ConstrainClippingRegion(NULL);
return CAIRO_INT_STATUS_SUCCESS;
}
int count = cairo_region_num_rectangles (region);
BRegion bregion;
for (int i = 0; i < count; ++i) {
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (region, i, &rect);
// Have to subtract one, because for pixman, the second coordinate
// lies outside the rectangle.
bregion.Include (_cairo_rectangle_to_brect (&rect));
}
surface->view->ConstrainClippingRegion(&bregion);
return CAIRO_INT_STATUS_SUCCESS;
}
/**
* _cairo_beos_bitmap_to_surface:
*
* Returns an addrefed image surface for a BBitmap. The bitmap need not outlive
* the surface.
**/
static cairo_image_surface_t*
_cairo_beos_bitmap_to_surface (BBitmap* bitmap)
{
color_space format = bitmap->ColorSpace();
if (format != B_RGB32 && format != B_RGBA32) {
BBitmap bmp(bitmap->Bounds(), B_RGB32, true);
BView view(bitmap->Bounds(), "Cairo bitmap drawing view",
B_FOLLOW_ALL_SIDES, 0);
bmp.AddChild(&view);
view.LockLooper();
view.DrawBitmap(bitmap, BPoint(0.0, 0.0));
view.Sync();
cairo_image_surface_t* imgsurf = _cairo_beos_bitmap_to_surface(&bmp);
view.UnlockLooper();
bmp.RemoveChild(&view);
return imgsurf;
}
cairo_format_t cformat = format == B_RGB32 ?
CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
BRect bounds(bitmap->Bounds());
unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits());
int width = bounds.IntegerWidth() + 1;
int height = bounds.IntegerHeight() + 1;
unsigned char* premultiplied;
if (cformat == CAIRO_FORMAT_ARGB32) {
premultiplied = premultiply_bgra (bits, width, height,
bitmap->BytesPerRow());
} else {
premultiplied = reinterpret_cast<unsigned char*>(
_cairo_malloc_ab(bitmap->BytesPerRow(), height));
if (premultiplied)
memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
}
if (!premultiplied)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*>
(cairo_image_surface_create_for_data(premultiplied,
cformat,
width,
height,
bitmap->BytesPerRow()));
if (surf->base.status)
free(premultiplied);
else
_cairo_image_surface_assume_ownership_of_data(surf);
return surf;
}
/**
* _cairo_image_surface_to_bitmap:
*
* Converts an image surface to a BBitmap. The return value must be freed with
* delete.
**/
static BBitmap*
_cairo_image_surface_to_bitmap (cairo_image_surface_t* surface)
{
BRect size(0.0, 0.0, surface->width - 1, surface->height - 1);
switch (surface->format) {
case CAIRO_FORMAT_ARGB32: {
BBitmap* data = new BBitmap(size, B_RGBA32);
unpremultiply_bgra (surface->data,
surface->width,
surface->height,
surface->stride,
reinterpret_cast<unsigned char*>(data->Bits()));
return data;
}
case CAIRO_FORMAT_RGB24: {
BBitmap* data = new BBitmap(size, B_RGB32);
memcpy(data->Bits(), surface->data, surface->height * surface->stride);
return data;
}
default:
assert(0);
return NULL;
}
}
/**
* _cairo_op_to_be_op:
*
* Converts a cairo drawing operator to a beos drawing_mode. Returns true if
* the operator could be converted, false otherwise.
**/
static bool
_cairo_op_to_be_op (cairo_operator_t cairo_op,
drawing_mode* beos_op)
{
switch (cairo_op) {
case CAIRO_OPERATOR_SOURCE:
*beos_op = B_OP_COPY;
return true;
case CAIRO_OPERATOR_OVER:
*beos_op = B_OP_ALPHA;
return true;
case CAIRO_OPERATOR_ADD:
// Does not actually work
// XXX This is a fundamental compositing operator, it has to work!
#if 1
return false;
#else
*beos_op = B_OP_ADD;
return true;
#endif
case CAIRO_OPERATOR_CLEAR:
// Does not map to B_OP_ERASE - it replaces the dest with the low
// color, instead of transparency; could be done by setting low
// color appropriately.
case CAIRO_OPERATOR_IN:
case CAIRO_OPERATOR_OUT:
case CAIRO_OPERATOR_ATOP:
case CAIRO_OPERATOR_DEST:
case CAIRO_OPERATOR_DEST_OVER:
case CAIRO_OPERATOR_DEST_IN:
case CAIRO_OPERATOR_DEST_OUT:
case CAIRO_OPERATOR_DEST_ATOP:
case CAIRO_OPERATOR_XOR:
case CAIRO_OPERATOR_SATURATE:
default:
return false;
}
}
static cairo_surface_t *
_cairo_beos_surface_create_similar (void *abstract_surface,
cairo_content_t content,
int width,
int height)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
if (width <= 0)
width = 1;
if (height <= 0)
height = 1;
BRect rect(0.0, 0.0, width - 1, height - 1);
BBitmap* bmp;
switch (content) {
case CAIRO_CONTENT_ALPHA:
return NULL;
case CAIRO_CONTENT_COLOR_ALPHA:
bmp = new BBitmap(rect, B_RGBA32, true);
break;
case CAIRO_CONTENT_COLOR:
// Match the color depth
if (surface->bitmap) {
color_space space = surface->bitmap->ColorSpace();
// No alpha was requested -> make sure not to return
// a surface with alpha
if (space == B_RGBA32)
space = B_RGB32;
if (space == B_RGBA15)
space = B_RGB15;
bmp = new BBitmap(rect, space, true);
} else {
BScreen scr(surface->view->Window());
color_space space = B_RGB32;
if (scr.IsValid())
space = scr.ColorSpace();
bmp = new BBitmap(rect, space, true);
}
break;
default:
ASSERT_NOT_REACHED;
return NULL;
}
BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);
bmp->AddChild(view);
return _cairo_beos_surface_create_internal(view, bmp, true);
}
static cairo_status_t
_cairo_beos_surface_finish (void *abstract_surface)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
if (surface->owns_bitmap_view) {
if (surface->bitmap)
surface->bitmap->RemoveChild(surface->view);
delete surface->view;
delete surface->bitmap;
surface->view = NULL;
surface->bitmap = NULL;
}
cairo_region_destroy (surface->clip_region);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_beos_surface_acquire_source_image (void *abstract_surface,
cairo_image_surface_t **image_out,
void **image_extra)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
AutoLockView locker(surface->view);
if (!locker)
return CAIRO_STATUS_NO_MEMORY; /// XXX not exactly right, but what can we do?
surface->view->Sync();
if (surface->bitmap) {
*image_out = _cairo_beos_bitmap_to_surface (surface->bitmap);
if (unlikely ((*image_out)->base.status))
return (*image_out)->base.status;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
BBitmap* bmp;
if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK)
return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
*image_out = _cairo_beos_bitmap_to_surface (bmp);
if (unlikely ((*image_out)->base.status)) {
delete bmp;
return (*image_out)->base.status;
}
*image_extra = bmp;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_beos_surface_release_source_image (void *abstract_surface,
cairo_image_surface_t *image,
void *image_extra)
{
cairo_surface_destroy (&image->base);
if (image_extra != NULL) {
BBitmap* bmp = static_cast<BBitmap*>(image_extra);
delete bmp;
}
}
static cairo_status_t
_cairo_beos_surface_acquire_dest_image (void *abstract_surface,
cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t **image_out,
cairo_rectangle_int_t *image_rect,
void **image_extra)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
AutoLockView locker(surface->view);
if (!locker) {
*image_out = NULL;
*image_extra = NULL;
return (cairo_status_t) CAIRO_INT_STATUS_NOTHING_TO_DO;
}
if (surface->bitmap) {
surface->view->Sync();
*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
if (unlikely ((*image_out)->base.status))
return (*image_out)->base.status;
image_rect->x = 0;
image_rect->y = 0;
image_rect->width = (*image_out)->width;
image_rect->height = (*image_out)->height;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
BRect b_interest_rect (_cairo_rectangle_to_brect (interest_rect));
BRect rect;
BBitmap* bitmap;
ViewCopyStatus status = _cairo_beos_view_to_bitmap(surface->view, &bitmap,
&rect, &b_interest_rect);
if (status == NOT_VISIBLE) {
*image_out = NULL;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
if (status == ERROR)
return CAIRO_STATUS_NO_MEMORY;
*image_rect = _brect_to_cairo_rectangle(rect);
*image_out = _cairo_beos_bitmap_to_surface(bitmap);
delete bitmap;
if (unlikely ((*image_out)->base.status))
return (*image_out)->base.status;
*image_extra = NULL;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_beos_surface_release_dest_image (void *abstract_surface,
cairo_rectangle_int_t *intersect_rect,
cairo_image_surface_t *image,
cairo_rectangle_int_t *image_rect,
void *image_extra)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
AutoLockView locker(surface->view);
if (!locker)
return;
BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
surface->view->PushState();
surface->view->SetDrawingMode(B_OP_COPY);
surface->view->DrawBitmap (bitmap_to_draw,
_cairo_rectangle_to_brect (image_rect));
surface->view->PopState();
delete bitmap_to_draw;
cairo_surface_destroy(&image->base);
}
static cairo_int_status_t
_cairo_beos_surface_composite (cairo_operator_t op,
cairo_pattern_t *src,
cairo_pattern_t *mask,
void *dst,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height,
cairo_region_t *clip_region)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
dst);
cairo_int_status_t status;
AutoLockView locker(surface->view);
if (!locker)
return CAIRO_INT_STATUS_SUCCESS;
drawing_mode mode;
if (!_cairo_op_to_be_op(op, &mode))
return CAIRO_INT_STATUS_UNSUPPORTED;
// XXX Masks are not yet supported
if (mask)
return CAIRO_INT_STATUS_UNSUPPORTED;
// XXX should eventually support the others
if (src->type != CAIRO_PATTERN_TYPE_SURFACE ||
src->extend != CAIRO_EXTEND_NONE)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
// Can we maybe support other matrices as well? (scale? if the filter is right)
int itx, ity;
if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_beos_surface_set_clip_region (surface, clip_region);
if (unlikely (status))
return status;
BRect srcRect(src_x + itx,
src_y + ity,
src_x + itx + width - 1,
src_y + ity + height - 1);
BRect dstRect(dst_x, dst_y, dst_x + width - 1, dst_y + height - 1);
cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)->
surface;
// Get a bitmap
BBitmap* bmp = NULL;
bool free_bmp = false;
if (_cairo_surface_is_image(src_surface)) {
cairo_image_surface_t* img_surface =
reinterpret_cast<cairo_image_surface_t*>(src_surface);
bmp = _cairo_image_surface_to_bitmap(img_surface);
free_bmp = true;
} else if (src_surface->backend == surface->base.backend) {
cairo_beos_surface_t *beos_surface =
reinterpret_cast<cairo_beos_surface_t*>(src_surface);
if (beos_surface->bitmap) {
AutoLockView locker(beos_surface->view);
if (locker)
beos_surface->view->Sync();
bmp = beos_surface->bitmap;
} else {
_cairo_beos_view_to_bitmap(surface->view, &bmp);
free_bmp = true;
}
}
if (!bmp)
return CAIRO_INT_STATUS_UNSUPPORTED;
// So, BeOS seems to screw up painting an opaque bitmap onto a
// translucent one (it makes them partly transparent). Just return
// unsupported.
if (bmp->ColorSpace() == B_RGB32 && surface->bitmap &&
surface->bitmap->ColorSpace() == B_RGBA32 &&
(mode == B_OP_COPY || mode == B_OP_ALPHA))
{
if (free_bmp)
delete bmp;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
// Draw it on screen.
surface->view->PushState();
// If our image rect is only a subrect of the desired size, and we
// aren't using B_OP_ALPHA, then we need to fill the rect first.
if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) {
rgb_color black = { 0, 0, 0, 0 };
surface->view->SetDrawingMode(mode);
surface->view->SetHighColor(black);
surface->view->FillRect(dstRect);
}
if (mode == B_OP_ALPHA && bmp->ColorSpace() == B_RGB32) {
mode = B_OP_COPY;
}
surface->view->SetDrawingMode(mode);
if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
else
surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
surface->view->DrawBitmap(bmp, srcRect, dstRect);
surface->view->PopState();
if (free_bmp)
delete bmp;
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_beos_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_int_t *rects,
int num_rects,
cairo_region_t *clip_region)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
cairo_int_status_t status;
if (num_rects <= 0)
return CAIRO_INT_STATUS_SUCCESS;
AutoLockView locker(surface->view);
if (!locker)
return CAIRO_INT_STATUS_SUCCESS;
drawing_mode mode;
if (!_cairo_op_to_be_op(op, &mode))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_beos_surface_set_clip_region (surface, clip_region);
if (unlikely (status))
return status;
rgb_color be_color = _cairo_color_to_be_color(color);
if (mode == B_OP_ALPHA && be_color.alpha == 0xFF)
mode = B_OP_COPY;
// For CAIRO_OPERATOR_SOURCE, cairo expects us to use the premultiplied
// color info. This is only relevant when drawing into an rgb24 buffer
// (as for others, we can convert when asked for the image)
if (mode == B_OP_COPY && be_color.alpha != 0xFF &&
(!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32))
{
be_color.red = color->red_short >> 8;
be_color.green = color->green_short >> 8;
be_color.blue = color->blue_short >> 8;
}
surface->view->PushState();
surface->view->SetDrawingMode(mode);
surface->view->SetHighColor(be_color);
if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
else
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
for (int i = 0; i < num_rects; ++i)
surface->view->FillRect (_cairo_rectangle_to_brect (&rects[i]));
surface->view->PopState();
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_bool_t
_cairo_beos_surface_get_extents (void *abstract_surface,
cairo_rectangle_int_t *rectangle)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
AutoLockView locker(surface->view);
if (!locker)
return FALSE;
*rectangle = _brect_to_cairo_rectangle (surface->view->Bounds());
return TRUE;
}
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
CAIRO_SURFACE_TYPE_BEOS,
_cairo_beos_surface_create_similar,
_cairo_beos_surface_finish,
_cairo_beos_surface_acquire_source_image,
_cairo_beos_surface_release_source_image,
_cairo_beos_surface_acquire_dest_image,
_cairo_beos_surface_release_dest_image,
NULL, /* clone_similar */
_cairo_beos_surface_composite, /* composite */
_cairo_beos_surface_fill_rectangles,
NULL, /* composite_trapezoids */
NULL, /* create_span_renderer */
NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
_cairo_beos_surface_get_extents,
NULL, /* old_show_glyphs */
NULL, /* get_font_options */
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
NULL, /* scaled_font_fini */
NULL, /* scaled_glyph_fini */
NULL, /* paint */
NULL, /* mask */
NULL, /* stroke */
NULL, /* fill */
NULL /* show_glyphs */
};
static cairo_surface_t *
_cairo_beos_surface_create_internal (BView* view,
BBitmap* bmp,
bool owns_bitmap_view)
{
// Must use malloc, because cairo code will use free() on the surface
cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
malloc(sizeof(cairo_beos_surface_t)));
if (surface == NULL) {
_cairo_error (CAIRO_STATUS_NO_MEMORY);
return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
}
cairo_content_t content = CAIRO_CONTENT_COLOR;
if (bmp && (bmp->ColorSpace() == B_RGBA32 || bmp->ColorSpace() == B_RGBA15))
content = CAIRO_CONTENT_COLOR_ALPHA;
_cairo_surface_init (&surface->base,
&cairo_beos_surface_backend,
NULL, /* device */
content);
surface->view = view;
surface->bitmap = bmp;
surface->owns_bitmap_view = owns_bitmap_view;
surface->clip_region = NULL;
return &surface->base;
}
/**
* cairo_beos_surface_create:
* @view: The view to draw on
*
* Creates a Cairo surface that draws onto a BeOS BView.
* The caller must ensure that the view does not get deleted before the surface.
* If the view is attached to a bitmap rather than an on-screen window, use
* cairo_beos_surface_create_for_bitmap() instead of this function.
*
* Since: TBD
**/
cairo_surface_t *
cairo_beos_surface_create (BView* view)
{
return cairo_beos_surface_create_for_bitmap(view, NULL);
}
/**
* cairo_beos_surface_create_for_bitmap:
* @view: The view to draw on
* @bmp: The bitmap to which the view is attached
*
* Creates a Cairo surface that draws onto a BeOS BView which is attached to a
* BBitmap.
* The caller must ensure that the view and the bitmap do not get deleted
* before the surface.
*
* For views that draw to a bitmap (as opposed to a screen), use this function
* rather than cairo_beos_surface_create(). Not using this function WILL lead to
* incorrect behaviour.
*
* For now, only views that draw to the entire area of bmp are supported.
* The view must already be attached to the bitmap.
*
* Since: TBD
**/
cairo_surface_t *
cairo_beos_surface_create_for_bitmap (BView* view,
BBitmap* bmp)
{
return _cairo_beos_surface_create_internal(view, bmp);
}

View File

@@ -0,0 +1,60 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Christian Biesinger <cbiesinger@web.de>
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Christian Biesinger
* <cbiesinger@web.de>
*
* Contributor(s):
*/
#ifndef CAIRO_BEOS_H
#define CAIRO_BEOS_H
#include "cairo.h"
#if CAIRO_HAS_BEOS_SURFACE
#include <View.h>
CAIRO_BEGIN_DECLS
cairo_public cairo_surface_t *
cairo_beos_surface_create (BView* view);
cairo_public cairo_surface_t *
cairo_beos_surface_create_for_bitmap (BView* view,
BBitmap* bmp);
CAIRO_END_DECLS
#else /* CAIRO_HAS_BEOS_SURFACE */
# error Cairo was not compiled with support for the beos backend
#endif /* CAIRO_HAS_BEOS_SURFACE */
#endif /* CAIRO_BEOS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,121 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2010 Andrea Canciani
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Andrea Canciani <ranma42@gmail.com>
*/
#ifndef CAIRO_BOX_H
#define CAIRO_BOX_H
#include "cairo-types-private.h"
#include "cairo-compiler-private.h"
#include "cairo-fixed-private.h"
static inline void
_cairo_box_set (cairo_box_t *box,
const cairo_point_t *p1,
const cairo_point_t *p2)
{
box->p1 = *p1;
box->p2 = *p2;
}
static inline void
_cairo_box_from_integers (cairo_box_t *box, int x, int y, int w, int h)
{
box->p1.x = _cairo_fixed_from_int (x);
box->p1.y = _cairo_fixed_from_int (y);
box->p2.x = _cairo_fixed_from_int (x + w);
box->p2.y = _cairo_fixed_from_int (y + h);
}
/* assumes box->p1 is top-left, p2 bottom-right */
static inline void
_cairo_box_add_point (cairo_box_t *box,
const cairo_point_t *point)
{
if (point->x < box->p1.x)
box->p1.x = point->x;
else if (point->x > box->p2.x)
box->p2.x = point->x;
if (point->y < box->p1.y)
box->p1.y = point->y;
else if (point->y > box->p2.y)
box->p2.y = point->y;
}
static inline void
_cairo_box_add_box (cairo_box_t *box,
const cairo_box_t *add)
{
if (add->p1.x < box->p1.x)
box->p1.x = add->p1.x;
if (add->p2.x > box->p2.x)
box->p2.x = add->p2.x;
if (add->p1.y < box->p1.y)
box->p1.y = add->p1.y;
if (add->p2.y > box->p2.y)
box->p2.y = add->p2.y;
}
/* assumes box->p1 is top-left, p2 bottom-right */
static inline cairo_bool_t
_cairo_box_contains_point (const cairo_box_t *box,
const cairo_point_t *point)
{
return box->p1.x <= point->x && point->x <= box->p2.x &&
box->p1.y <= point->y && point->y <= box->p2.y;
}
static inline cairo_bool_t
_cairo_box_is_pixel_aligned (const cairo_box_t *box)
{
#if CAIRO_FIXED_FRAC_BITS <= 8 && 0
return ((box->p1.x & CAIRO_FIXED_FRAC_MASK) << 24 |
(box->p1.y & CAIRO_FIXED_FRAC_MASK) << 16 |
(box->p2.x & CAIRO_FIXED_FRAC_MASK) << 8 |
(box->p2.y & CAIRO_FIXED_FRAC_MASK) << 0) == 0;
#else /* GCC on i7 prefers this variant (bizarrely according to the profiler) */
cairo_fixed_t f;
f = 0;
f |= box->p1.x & CAIRO_FIXED_FRAC_MASK;
f |= box->p1.y & CAIRO_FIXED_FRAC_MASK;
f |= box->p2.x & CAIRO_FIXED_FRAC_MASK;
f |= box->p2.y & CAIRO_FIXED_FRAC_MASK;
return f == 0;
#endif
}
#endif /* CAIRO_BOX_H */

View File

@@ -0,0 +1,690 @@
/*
* Copyright © 2004 Carl Worth
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Carl Worth
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
/* Provide definitions for standalone compilation */
#include "cairoint.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
#include "cairo-combsort-inline.h"
#include "cairo-list-private.h"
#include <setjmp.h>
typedef struct _rectangle rectangle_t;
typedef struct _edge edge_t;
struct _edge {
edge_t *next, *prev;
edge_t *right;
cairo_fixed_t x, top;
int a_or_b;
int dir;
};
struct _rectangle {
edge_t left, right;
int32_t top, bottom;
};
#define UNROLL3(x) x x x
/* the parent is always given by index/2 */
#define PQ_PARENT_INDEX(i) ((i) >> 1)
#define PQ_FIRST_ENTRY 1
/* left and right children are index * 2 and (index * 2) +1 respectively */
#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
typedef struct _pqueue {
int size, max_size;
rectangle_t **elements;
rectangle_t *elements_embedded[1024];
} pqueue_t;
typedef struct _sweep_line {
rectangle_t **rectangles;
pqueue_t pq;
edge_t head, tail;
edge_t *insert_left, *insert_right;
int32_t current_y;
int32_t last_y;
jmp_buf unwind;
} sweep_line_t;
#define DEBUG_TRAPS 0
#if DEBUG_TRAPS
static void
dump_traps (cairo_traps_t *traps, const char *filename)
{
FILE *file;
int n;
if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
return;
file = fopen (filename, "a");
if (file != NULL) {
for (n = 0; n < traps->num_traps; n++) {
fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n",
traps->traps[n].top,
traps->traps[n].bottom,
traps->traps[n].left.p1.x,
traps->traps[n].left.p1.y,
traps->traps[n].left.p2.x,
traps->traps[n].left.p2.y,
traps->traps[n].right.p1.x,
traps->traps[n].right.p1.y,
traps->traps[n].right.p2.x,
traps->traps[n].right.p2.y);
}
fprintf (file, "\n");
fclose (file);
}
}
#else
#define dump_traps(traps, filename)
#endif
static inline int
rectangle_compare_start (const rectangle_t *a,
const rectangle_t *b)
{
return a->top - b->top;
}
static inline int
rectangle_compare_stop (const rectangle_t *a,
const rectangle_t *b)
{
return a->bottom - b->bottom;
}
static inline void
pqueue_init (pqueue_t *pq)
{
pq->max_size = ARRAY_LENGTH (pq->elements_embedded);
pq->size = 0;
pq->elements = pq->elements_embedded;
pq->elements[PQ_FIRST_ENTRY] = NULL;
}
static inline void
pqueue_fini (pqueue_t *pq)
{
if (pq->elements != pq->elements_embedded)
free (pq->elements);
}
static cairo_bool_t
pqueue_grow (pqueue_t *pq)
{
rectangle_t **new_elements;
pq->max_size *= 2;
if (pq->elements == pq->elements_embedded) {
new_elements = _cairo_malloc_ab (pq->max_size,
sizeof (rectangle_t *));
if (unlikely (new_elements == NULL))
return FALSE;
memcpy (new_elements, pq->elements_embedded,
sizeof (pq->elements_embedded));
} else {
new_elements = _cairo_realloc_ab (pq->elements,
pq->max_size,
sizeof (rectangle_t *));
if (unlikely (new_elements == NULL))
return FALSE;
}
pq->elements = new_elements;
return TRUE;
}
static inline void
pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle)
{
rectangle_t **elements;
int i, parent;
if (unlikely (sweep->pq.size + 1 == sweep->pq.max_size)) {
if (unlikely (! pqueue_grow (&sweep->pq))) {
longjmp (sweep->unwind,
_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
}
elements = sweep->pq.elements;
for (i = ++sweep->pq.size;
i != PQ_FIRST_ENTRY &&
rectangle_compare_stop (rectangle,
elements[parent = PQ_PARENT_INDEX (i)]) < 0;
i = parent)
{
elements[i] = elements[parent];
}
elements[i] = rectangle;
}
static inline void
pqueue_pop (pqueue_t *pq)
{
rectangle_t **elements = pq->elements;
rectangle_t *tail;
int child, i;
tail = elements[pq->size--];
if (pq->size == 0) {
elements[PQ_FIRST_ENTRY] = NULL;
return;
}
for (i = PQ_FIRST_ENTRY;
(child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size;
i = child)
{
if (child != pq->size &&
rectangle_compare_stop (elements[child+1],
elements[child]) < 0)
{
child++;
}
if (rectangle_compare_stop (elements[child], tail) >= 0)
break;
elements[i] = elements[child];
}
elements[i] = tail;
}
static inline rectangle_t *
rectangle_pop_start (sweep_line_t *sweep_line)
{
return *sweep_line->rectangles++;
}
static inline rectangle_t *
rectangle_peek_stop (sweep_line_t *sweep_line)
{
return sweep_line->pq.elements[PQ_FIRST_ENTRY];
}
CAIRO_COMBSORT_DECLARE (_rectangle_sort,
rectangle_t *,
rectangle_compare_start)
static void
sweep_line_init (sweep_line_t *sweep_line,
rectangle_t **rectangles,
int num_rectangles)
{
_rectangle_sort (rectangles, num_rectangles);
rectangles[num_rectangles] = NULL;
sweep_line->rectangles = rectangles;
sweep_line->head.x = INT32_MIN;
sweep_line->head.right = NULL;
sweep_line->head.dir = 0;
sweep_line->head.next = &sweep_line->tail;
sweep_line->tail.x = INT32_MAX;
sweep_line->tail.right = NULL;
sweep_line->tail.dir = 0;
sweep_line->tail.prev = &sweep_line->head;
sweep_line->insert_left = &sweep_line->tail;
sweep_line->insert_right = &sweep_line->tail;
sweep_line->current_y = INT32_MIN;
sweep_line->last_y = INT32_MIN;
pqueue_init (&sweep_line->pq);
}
static void
sweep_line_fini (sweep_line_t *sweep_line)
{
pqueue_fini (&sweep_line->pq);
}
static void
end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot, cairo_boxes_t *out)
{
if (likely (left->top < bot)) {
cairo_status_t status;
cairo_box_t box;
box.p1.x = left->x;
box.p1.y = left->top;
box.p2.x = left->right->x;
box.p2.y = bot;
status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
if (unlikely (status))
longjmp (sweep_line->unwind, status);
}
left->right = NULL;
}
/* Start a new trapezoid at the given top y coordinate, whose edges
* are `edge' and `edge->next'. If `edge' already has a trapezoid,
* then either add it to the traps in `traps', if the trapezoid's
* right edge differs from `edge->next', or do nothing if the new
* trapezoid would be a continuation of the existing one. */
static inline void
start_or_continue_box (sweep_line_t *sweep_line,
edge_t *left,
edge_t *right,
int top,
cairo_boxes_t *out)
{
if (left->right == right)
return;
if (left->right != NULL) {
if (right != NULL && left->right->x == right->x) {
/* continuation on right, so just swap edges */
left->right = right;
return;
}
end_box (sweep_line, left, top, out);
}
if (right != NULL && left->x != right->x) {
left->top = top;
left->right = right;
}
}
static inline int is_zero(const int *winding)
{
return winding[0] == 0 || winding[1] == 0;
}
static inline void
active_edges (sweep_line_t *sweep, cairo_boxes_t *out)
{
int top = sweep->current_y;
int winding[2] = { 0 };
edge_t *pos;
if (sweep->last_y == sweep->current_y)
return;
pos = sweep->head.next;
if (pos == &sweep->tail)
return;
do {
edge_t *left, *right;
left = pos;
do {
winding[left->a_or_b] += left->dir;
if (!is_zero (winding))
break;
if (left->next == &sweep->tail)
goto out;
if (unlikely (left->right != NULL))
end_box (sweep, left, top, out);
left = left->next;
} while (1);
right = left->next;
do {
if (unlikely (right->right != NULL))
end_box (sweep, right, top, out);
winding[right->a_or_b] += right->dir;
if (is_zero (winding)) {
/* skip co-linear edges */
if (likely (right->x != right->next->x))
break;
}
right = right->next;
} while (TRUE);
start_or_continue_box (sweep, left, right, top, out);
pos = right->next;
} while (pos != &sweep->tail);
out:
sweep->last_y = sweep->current_y;
}
static inline void
sweep_line_delete_edge (sweep_line_t *sweep_line, edge_t *edge, cairo_boxes_t *out)
{
if (edge->right != NULL) {
edge_t *next = edge->next;
if (next->x == edge->x) {
next->top = edge->top;
next->right = edge->right;
} else {
end_box (sweep_line, edge, sweep_line->current_y, out);
}
}
if (sweep_line->insert_left == edge)
sweep_line->insert_left = edge->next;
if (sweep_line->insert_right == edge)
sweep_line->insert_right = edge->next;
edge->prev->next = edge->next;
edge->next->prev = edge->prev;
}
static inline void
sweep_line_delete (sweep_line_t *sweep,
rectangle_t *rectangle,
cairo_boxes_t *out)
{
sweep_line_delete_edge (sweep, &rectangle->left, out);
sweep_line_delete_edge (sweep, &rectangle->right, out);
pqueue_pop (&sweep->pq);
}
static inline void
insert_edge (edge_t *edge, edge_t *pos)
{
if (pos->x != edge->x) {
if (pos->x > edge->x) {
do {
UNROLL3({
if (pos->prev->x <= edge->x)
break;
pos = pos->prev;
})
} while (TRUE);
} else {
do {
UNROLL3({
pos = pos->next;
if (pos->x >= edge->x)
break;
})
} while (TRUE);
}
}
pos->prev->next = edge;
edge->prev = pos->prev;
edge->next = pos;
pos->prev = edge;
}
static inline void
sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle)
{
edge_t *pos;
/* right edge */
pos = sweep->insert_right;
insert_edge (&rectangle->right, pos);
sweep->insert_right = &rectangle->right;
/* left edge */
pos = sweep->insert_left;
if (pos->x > sweep->insert_right->x)
pos = sweep->insert_right->prev;
insert_edge (&rectangle->left, pos);
sweep->insert_left = &rectangle->left;
pqueue_push (sweep, rectangle);
}
static cairo_status_t
intersect (rectangle_t **rectangles, int num_rectangles, cairo_boxes_t *out)
{
sweep_line_t sweep_line;
rectangle_t *rectangle;
cairo_status_t status;
sweep_line_init (&sweep_line, rectangles, num_rectangles);
if ((status = setjmp (sweep_line.unwind)))
goto unwind;
rectangle = rectangle_pop_start (&sweep_line);
do {
if (rectangle->top != sweep_line.current_y) {
rectangle_t *stop;
stop = rectangle_peek_stop (&sweep_line);
while (stop != NULL && stop->bottom < rectangle->top) {
if (stop->bottom != sweep_line.current_y) {
active_edges (&sweep_line, out);
sweep_line.current_y = stop->bottom;
}
sweep_line_delete (&sweep_line, stop, out);
stop = rectangle_peek_stop (&sweep_line);
}
active_edges (&sweep_line, out);
sweep_line.current_y = rectangle->top;
}
sweep_line_insert (&sweep_line, rectangle);
} while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL);
while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) {
if (rectangle->bottom != sweep_line.current_y) {
active_edges (&sweep_line, out);
sweep_line.current_y = rectangle->bottom;
}
sweep_line_delete (&sweep_line, rectangle, out);
}
unwind:
sweep_line_fini (&sweep_line);
return status;
}
static cairo_status_t
_cairo_boxes_intersect_with_box (const cairo_boxes_t *boxes,
const cairo_box_t *box,
cairo_boxes_t *out)
{
cairo_status_t status;
int i, j;
if (out == boxes) { /* inplace update */
struct _cairo_boxes_chunk *chunk;
out->num_boxes = 0;
for (chunk = &out->chunks; chunk != NULL; chunk = chunk->next) {
for (i = j = 0; i < chunk->count; i++) {
cairo_box_t *b = &chunk->base[i];
b->p1.x = MAX (b->p1.x, box->p1.x);
b->p1.y = MAX (b->p1.y, box->p1.y);
b->p2.x = MIN (b->p2.x, box->p2.x);
b->p2.y = MIN (b->p2.y, box->p2.y);
if (b->p1.x < b->p2.x && b->p1.y < b->p2.y) {
if (i != j)
chunk->base[j] = *b;
j++;
}
}
/* XXX unlink empty chains? */
chunk->count = j;
out->num_boxes += j;
}
} else {
const struct _cairo_boxes_chunk *chunk;
_cairo_boxes_clear (out);
_cairo_boxes_limit (out, box, 1);
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
status = _cairo_boxes_add (out,
CAIRO_ANTIALIAS_DEFAULT,
&chunk->base[i]);
if (unlikely (status))
return status;
}
}
}
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_boxes_intersect (const cairo_boxes_t *a,
const cairo_boxes_t *b,
cairo_boxes_t *out)
{
rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
rectangle_t *rectangles;
rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1];
rectangle_t **rectangles_ptrs;
const struct _cairo_boxes_chunk *chunk;
cairo_status_t status;
int i, j, count;
if (unlikely (a->num_boxes == 0 || b->num_boxes == 0)) {
_cairo_boxes_clear (out);
return CAIRO_STATUS_SUCCESS;
}
if (a->num_boxes == 1) {
cairo_box_t box = a->chunks.base[0];
return _cairo_boxes_intersect_with_box (b, &box, out);
}
if (b->num_boxes == 1) {
cairo_box_t box = b->chunks.base[0];
return _cairo_boxes_intersect_with_box (a, &box, out);
}
rectangles = stack_rectangles;
rectangles_ptrs = stack_rectangles_ptrs;
count = a->num_boxes + b->num_boxes;
if (count > ARRAY_LENGTH (stack_rectangles)) {
rectangles = _cairo_malloc_ab_plus_c (count,
sizeof (rectangle_t) +
sizeof (rectangle_t *),
sizeof (rectangle_t *));
if (unlikely (rectangles == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
rectangles_ptrs = (rectangle_t **) (rectangles + count);
}
j = 0;
for (chunk = &a->chunks; chunk != NULL; chunk = chunk->next) {
const cairo_box_t *box = chunk->base;
for (i = 0; i < chunk->count; i++) {
if (box[i].p1.x < box[i].p2.x) {
rectangles[j].left.x = box[i].p1.x;
rectangles[j].left.dir = 1;
rectangles[j].right.x = box[i].p2.x;
rectangles[j].right.dir = -1;
} else {
rectangles[j].right.x = box[i].p1.x;
rectangles[j].right.dir = 1;
rectangles[j].left.x = box[i].p2.x;
rectangles[j].left.dir = -1;
}
rectangles[j].left.a_or_b = 0;
rectangles[j].left.right = NULL;
rectangles[j].right.a_or_b = 0;
rectangles[j].right.right = NULL;
rectangles[j].top = box[i].p1.y;
rectangles[j].bottom = box[i].p2.y;
rectangles_ptrs[j] = &rectangles[j];
j++;
}
}
for (chunk = &b->chunks; chunk != NULL; chunk = chunk->next) {
const cairo_box_t *box = chunk->base;
for (i = 0; i < chunk->count; i++) {
if (box[i].p1.x < box[i].p2.x) {
rectangles[j].left.x = box[i].p1.x;
rectangles[j].left.dir = 1;
rectangles[j].right.x = box[i].p2.x;
rectangles[j].right.dir = -1;
} else {
rectangles[j].right.x = box[i].p1.x;
rectangles[j].right.dir = 1;
rectangles[j].left.x = box[i].p2.x;
rectangles[j].left.dir = -1;
}
rectangles[j].left.a_or_b = 1;
rectangles[j].left.right = NULL;
rectangles[j].right.a_or_b = 1;
rectangles[j].right.right = NULL;
rectangles[j].top = box[i].p1.y;
rectangles[j].bottom = box[i].p2.y;
rectangles_ptrs[j] = &rectangles[j];
j++;
}
}
assert (j == count);
_cairo_boxes_clear (out);
status = intersect (rectangles_ptrs, j, out);
if (rectangles != stack_rectangles)
free (rectangles);
return status;
}

View File

@@ -0,0 +1,123 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2009 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_BOXES_H
#define CAIRO_BOXES_H
#include "cairo-types-private.h"
#include "cairo-compiler-private.h"
#include <stdio.h>
#include <stdlib.h>
struct _cairo_boxes_t {
cairo_status_t status;
cairo_box_t limit;
const cairo_box_t *limits;
int num_limits;
int num_boxes;
unsigned int is_pixel_aligned;
struct _cairo_boxes_chunk {
struct _cairo_boxes_chunk *next;
cairo_box_t *base;
int count;
int size;
} chunks, *tail;
cairo_box_t boxes_embedded[32];
};
cairo_private void
_cairo_boxes_init (cairo_boxes_t *boxes);
cairo_private void
_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
cairo_clip_t *clip);
cairo_private void
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
cairo_box_t *array,
int num_boxes);
cairo_private void
_cairo_boxes_init_from_rectangle (cairo_boxes_t *boxes,
int x, int y, int w, int h);
cairo_private void
_cairo_boxes_limit (cairo_boxes_t *boxes,
const cairo_box_t *limits,
int num_limits);
cairo_private cairo_status_t
_cairo_boxes_add (cairo_boxes_t *boxes,
cairo_antialias_t antialias,
const cairo_box_t *box);
cairo_private void
_cairo_boxes_extents (const cairo_boxes_t *boxes,
cairo_box_t *box);
cairo_private cairo_box_t *
_cairo_boxes_to_array (const cairo_boxes_t *boxes,
int *num_boxes,
cairo_bool_t force_allocation);
cairo_private cairo_status_t
_cairo_boxes_intersect (const cairo_boxes_t *a,
const cairo_boxes_t *b,
cairo_boxes_t *out);
cairo_private void
_cairo_boxes_clear (cairo_boxes_t *boxes);
cairo_private_no_warn cairo_bool_t
_cairo_boxes_for_each_box (cairo_boxes_t *boxes,
cairo_bool_t (*func) (cairo_box_t *box, void *data),
void *data);
cairo_private cairo_status_t
_cairo_rasterise_polygon_to_boxes (cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule,
cairo_boxes_t *boxes);
cairo_private void
_cairo_boxes_fini (cairo_boxes_t *boxes);
cairo_private void
_cairo_debug_print_boxes (FILE *stream,
const cairo_boxes_t *boxes);
#endif /* CAIRO_BOXES_H */

View File

@@ -0,0 +1,460 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2009 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-box-inline.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
void
_cairo_boxes_init (cairo_boxes_t *boxes)
{
boxes->status = CAIRO_STATUS_SUCCESS;
boxes->num_limits = 0;
boxes->num_boxes = 0;
boxes->tail = &boxes->chunks;
boxes->chunks.next = NULL;
boxes->chunks.base = boxes->boxes_embedded;
boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
boxes->chunks.count = 0;
boxes->is_pixel_aligned = TRUE;
}
void
_cairo_boxes_init_from_rectangle (cairo_boxes_t *boxes,
int x, int y, int w, int h)
{
_cairo_boxes_init (boxes);
_cairo_box_from_integers (&boxes->chunks.base[0], x, y, w, h);
boxes->num_boxes = 1;
}
void
_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
cairo_clip_t *clip)
{
_cairo_boxes_init (boxes);
if (clip)
_cairo_boxes_limit (boxes, clip->boxes, clip->num_boxes);
}
void
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
cairo_box_t *array,
int num_boxes)
{
int n;
boxes->status = CAIRO_STATUS_SUCCESS;
boxes->num_limits = 0;
boxes->num_boxes = num_boxes;
boxes->tail = &boxes->chunks;
boxes->chunks.next = NULL;
boxes->chunks.base = array;
boxes->chunks.size = num_boxes;
boxes->chunks.count = num_boxes;
for (n = 0; n < num_boxes; n++) {
if (! _cairo_fixed_is_integer (array[n].p1.x) ||
! _cairo_fixed_is_integer (array[n].p1.y) ||
! _cairo_fixed_is_integer (array[n].p2.x) ||
! _cairo_fixed_is_integer (array[n].p2.y))
{
break;
}
}
boxes->is_pixel_aligned = n == num_boxes;
}
void
_cairo_boxes_limit (cairo_boxes_t *boxes,
const cairo_box_t *limits,
int num_limits)
{
int n;
boxes->limits = limits;
boxes->num_limits = num_limits;
if (boxes->num_limits) {
boxes->limit = limits[0];
for (n = 1; n < num_limits; n++) {
if (limits[n].p1.x < boxes->limit.p1.x)
boxes->limit.p1.x = limits[n].p1.x;
if (limits[n].p1.y < boxes->limit.p1.y)
boxes->limit.p1.y = limits[n].p1.y;
if (limits[n].p2.x > boxes->limit.p2.x)
boxes->limit.p2.x = limits[n].p2.x;
if (limits[n].p2.y > boxes->limit.p2.y)
boxes->limit.p2.y = limits[n].p2.y;
}
}
}
static void
_cairo_boxes_add_internal (cairo_boxes_t *boxes,
const cairo_box_t *box)
{
struct _cairo_boxes_chunk *chunk;
if (unlikely (boxes->status))
return;
chunk = boxes->tail;
if (unlikely (chunk->count == chunk->size)) {
int size;
size = chunk->size * 2;
chunk->next = _cairo_malloc_ab_plus_c (size,
sizeof (cairo_box_t),
sizeof (struct _cairo_boxes_chunk));
if (unlikely (chunk->next == NULL)) {
boxes->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return;
}
chunk = chunk->next;
boxes->tail = chunk;
chunk->next = NULL;
chunk->count = 0;
chunk->size = size;
chunk->base = (cairo_box_t *) (chunk + 1);
}
chunk->base[chunk->count++] = *box;
boxes->num_boxes++;
if (boxes->is_pixel_aligned)
boxes->is_pixel_aligned = _cairo_box_is_pixel_aligned (box);
}
cairo_status_t
_cairo_boxes_add (cairo_boxes_t *boxes,
cairo_antialias_t antialias,
const cairo_box_t *box)
{
cairo_box_t b;
if (antialias == CAIRO_ANTIALIAS_NONE) {
b.p1.x = _cairo_fixed_round_down (box->p1.x);
b.p1.y = _cairo_fixed_round_down (box->p1.y);
b.p2.x = _cairo_fixed_round_down (box->p2.x);
b.p2.y = _cairo_fixed_round_down (box->p2.y);
box = &b;
}
if (box->p1.y == box->p2.y)
return CAIRO_STATUS_SUCCESS;
if (box->p1.x == box->p2.x)
return CAIRO_STATUS_SUCCESS;
if (boxes->num_limits) {
cairo_point_t p1, p2;
cairo_bool_t reversed = FALSE;
int n;
/* support counter-clockwise winding for rectangular tessellation */
if (box->p1.x < box->p2.x) {
p1.x = box->p1.x;
p2.x = box->p2.x;
} else {
p2.x = box->p1.x;
p1.x = box->p2.x;
reversed = ! reversed;
}
if (p1.x >= boxes->limit.p2.x || p2.x <= boxes->limit.p1.x)
return CAIRO_STATUS_SUCCESS;
if (box->p1.y < box->p2.y) {
p1.y = box->p1.y;
p2.y = box->p2.y;
} else {
p2.y = box->p1.y;
p1.y = box->p2.y;
reversed = ! reversed;
}
if (p1.y >= boxes->limit.p2.y || p2.y <= boxes->limit.p1.y)
return CAIRO_STATUS_SUCCESS;
for (n = 0; n < boxes->num_limits; n++) {
const cairo_box_t *limits = &boxes->limits[n];
cairo_box_t _box;
cairo_point_t _p1, _p2;
if (p1.x >= limits->p2.x || p2.x <= limits->p1.x)
continue;
if (p1.y >= limits->p2.y || p2.y <= limits->p1.y)
continue;
/* Otherwise, clip the box to the limits. */
_p1 = p1;
if (_p1.x < limits->p1.x)
_p1.x = limits->p1.x;
if (_p1.y < limits->p1.y)
_p1.y = limits->p1.y;
_p2 = p2;
if (_p2.x > limits->p2.x)
_p2.x = limits->p2.x;
if (_p2.y > limits->p2.y)
_p2.y = limits->p2.y;
if (_p2.y <= _p1.y || _p2.x <= _p1.x)
continue;
_box.p1.y = _p1.y;
_box.p2.y = _p2.y;
if (reversed) {
_box.p1.x = _p2.x;
_box.p2.x = _p1.x;
} else {
_box.p1.x = _p1.x;
_box.p2.x = _p2.x;
}
_cairo_boxes_add_internal (boxes, &_box);
}
} else {
_cairo_boxes_add_internal (boxes, box);
}
return boxes->status;
}
void
_cairo_boxes_extents (const cairo_boxes_t *boxes,
cairo_box_t *box)
{
const struct _cairo_boxes_chunk *chunk;
cairo_box_t b;
int i;
if (boxes->num_boxes == 0) {
box->p1.x = box->p1.y = box->p2.x = box->p2.y = 0;
return;
}
b = boxes->chunks.base[0];
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
if (chunk->base[i].p1.x < b.p1.x)
b.p1.x = chunk->base[i].p1.x;
if (chunk->base[i].p1.y < b.p1.y)
b.p1.y = chunk->base[i].p1.y;
if (chunk->base[i].p2.x > b.p2.x)
b.p2.x = chunk->base[i].p2.x;
if (chunk->base[i].p2.y > b.p2.y)
b.p2.y = chunk->base[i].p2.y;
}
}
*box = b;
}
void
_cairo_boxes_clear (cairo_boxes_t *boxes)
{
struct _cairo_boxes_chunk *chunk, *next;
for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
next = chunk->next;
free (chunk);
}
boxes->tail = &boxes->chunks;
boxes->chunks.next = 0;
boxes->chunks.count = 0;
boxes->chunks.base = boxes->boxes_embedded;
boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
boxes->num_boxes = 0;
boxes->is_pixel_aligned = TRUE;
}
cairo_box_t *
_cairo_boxes_to_array (const cairo_boxes_t *boxes,
int *num_boxes,
cairo_bool_t force_allocation)
{
const struct _cairo_boxes_chunk *chunk;
cairo_box_t *box;
int i, j;
*num_boxes = boxes->num_boxes;
if (boxes->chunks.next == NULL && ! force_allocation)
return boxes->chunks.base;
box = _cairo_malloc_ab (boxes->num_boxes, sizeof (cairo_box_t));
if (box == NULL) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
j = 0;
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++)
box[j++] = chunk->base[i];
}
return box;
}
void
_cairo_boxes_fini (cairo_boxes_t *boxes)
{
struct _cairo_boxes_chunk *chunk, *next;
for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
next = chunk->next;
free (chunk);
}
}
cairo_bool_t
_cairo_boxes_for_each_box (cairo_boxes_t *boxes,
cairo_bool_t (*func) (cairo_box_t *box, void *data),
void *data)
{
struct _cairo_boxes_chunk *chunk;
int i;
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++)
if (! func (&chunk->base[i], data))
return FALSE;
}
return TRUE;
}
struct cairo_box_renderer {
cairo_span_renderer_t base;
cairo_boxes_t *boxes;
};
static cairo_status_t
span_to_boxes (void *abstract_renderer, int y, int h,
const cairo_half_open_span_t *spans, unsigned num_spans)
{
struct cairo_box_renderer *r = abstract_renderer;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_box_t box;
if (num_spans == 0)
return CAIRO_STATUS_SUCCESS;
box.p1.y = _cairo_fixed_from_int (y);
box.p2.y = _cairo_fixed_from_int (y + h);
do {
if (spans[0].coverage) {
box.p1.x = _cairo_fixed_from_int(spans[0].x);
box.p2.x = _cairo_fixed_from_int(spans[1].x);
status = _cairo_boxes_add (r->boxes, CAIRO_ANTIALIAS_DEFAULT, &box);
}
spans++;
} while (--num_spans > 1 && status == CAIRO_STATUS_SUCCESS);
return status;
}
cairo_status_t
_cairo_rasterise_polygon_to_boxes (cairo_polygon_t *polygon,
cairo_fill_rule_t fill_rule,
cairo_boxes_t *boxes)
{
struct cairo_box_renderer renderer;
cairo_scan_converter_t *converter;
cairo_int_status_t status;
cairo_rectangle_int_t r;
TRACE ((stderr, "%s: fill_rule=%d\n", __FUNCTION__, fill_rule));
_cairo_box_round_to_rectangle (&polygon->extents, &r);
converter = _cairo_mono_scan_converter_create (r.x, r.y,
r.x + r.width,
r.y + r.height,
fill_rule);
status = _cairo_mono_scan_converter_add_polygon (converter, polygon);
if (unlikely (status))
goto cleanup_converter;
renderer.boxes = boxes;
renderer.base.render_rows = span_to_boxes;
status = converter->generate (converter, &renderer.base);
cleanup_converter:
converter->destroy (converter);
return status;
}
void
_cairo_debug_print_boxes (FILE *stream, const cairo_boxes_t *boxes)
{
const struct _cairo_boxes_chunk *chunk;
cairo_box_t extents;
int i;
_cairo_boxes_extents (boxes, &extents);
fprintf (stream, "boxes x %d: (%f, %f) x (%f, %f)\n",
boxes->num_boxes,
_cairo_fixed_to_double (extents.p1.x),
_cairo_fixed_to_double (extents.p1.y),
_cairo_fixed_to_double (extents.p2.x),
_cairo_fixed_to_double (extents.p2.y));
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
fprintf (stderr, " box[%d]: (%f, %f), (%f, %f)\n", i,
_cairo_fixed_to_double (chunk->base[i].p1.x),
_cairo_fixed_to_double (chunk->base[i].p1.y),
_cairo_fixed_to_double (chunk->base[i].p2.x),
_cairo_fixed_to_double (chunk->base[i].p2.y));
}
}
}

View File

@@ -0,0 +1,145 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Red Hat, Inc.
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#ifndef CAIRO_CACHE_PRIVATE_H
#define CAIRO_CACHE_PRIVATE_H
#include "cairo-compiler-private.h"
#include "cairo-types-private.h"
/**
* cairo_cache_entry_t:
*
* A #cairo_cache_entry_t contains both a key and a value for
* #cairo_cache_t. User-derived types for #cairo_cache_entry_t must
* have a #cairo_cache_entry_t as their first field. For example:
*
* typedef _my_entry {
* cairo_cache_entry_t base;
* ... Remainder of key and value fields here ..
* } my_entry_t;
*
* which then allows a pointer to my_entry_t to be passed to any of
* the #cairo_cache_t functions as follows without requiring a cast:
*
* _cairo_cache_insert (cache, &my_entry->base, size);
*
* IMPORTANT: The caller is responsible for initializing
* my_entry->base.hash with a hash code derived from the key. The
* essential property of the hash code is that keys_equal must never
* return %TRUE for two keys that have different hashes. The best hash
* code will reduce the frequency of two keys with the same code for
* which keys_equal returns %FALSE.
*
* The user must also initialize my_entry->base.size to indicate
* the size of the current entry. What units to use for size is
* entirely up to the caller, (though the same units must be used for
* the max_size parameter passed to _cairo_cache_create()). If all
* entries are close to the same size, the simplest thing to do is to
* just use units of "entries", (eg. set size==1 in all entries and
* set max_size to the number of entries which you want to be saved
* in the cache).
*
* Which parts of the entry make up the "key" and which part make up
* the value are entirely up to the caller, (as determined by the
* computation going into base.hash as well as the keys_equal
* function). A few of the #cairo_cache_t functions accept an entry which
* will be used exclusively as a "key", (indicated by a parameter name
* of key). In these cases, the value-related fields of the entry need
* not be initialized if so desired.
**/
typedef struct _cairo_cache_entry {
unsigned long hash;
unsigned long size;
} cairo_cache_entry_t;
typedef cairo_bool_t (*cairo_cache_predicate_func_t) (const void *entry);
struct _cairo_cache {
cairo_hash_table_t *hash_table;
cairo_cache_predicate_func_t predicate;
cairo_destroy_func_t entry_destroy;
unsigned long max_size;
unsigned long size;
int freeze_count;
};
typedef cairo_bool_t
(*cairo_cache_keys_equal_func_t) (const void *key_a, const void *key_b);
typedef void
(*cairo_cache_callback_func_t) (void *entry,
void *closure);
cairo_private cairo_status_t
_cairo_cache_init (cairo_cache_t *cache,
cairo_cache_keys_equal_func_t keys_equal,
cairo_cache_predicate_func_t predicate,
cairo_destroy_func_t entry_destroy,
unsigned long max_size);
cairo_private void
_cairo_cache_fini (cairo_cache_t *cache);
cairo_private void
_cairo_cache_freeze (cairo_cache_t *cache);
cairo_private void
_cairo_cache_thaw (cairo_cache_t *cache);
cairo_private void *
_cairo_cache_lookup (cairo_cache_t *cache,
cairo_cache_entry_t *key);
cairo_private cairo_status_t
_cairo_cache_insert (cairo_cache_t *cache,
cairo_cache_entry_t *entry);
cairo_private void
_cairo_cache_remove (cairo_cache_t *cache,
cairo_cache_entry_t *entry);
cairo_private void
_cairo_cache_foreach (cairo_cache_t *cache,
cairo_cache_callback_func_t cache_callback,
void *closure);
#endif

View File

@@ -0,0 +1,338 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2004 Red Hat, Inc.
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Keith Packard <keithp@keithp.com>
* Graydon Hoare <graydon@redhat.com>
* Carl Worth <cworth@cworth.org>
*/
#include "cairoint.h"
#include "cairo-error-private.h"
static void
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
unsigned long additional);
static cairo_bool_t
_cairo_cache_entry_is_non_zero (const void *entry)
{
return ((const cairo_cache_entry_t *) entry)->size;
}
/**
* _cairo_cache_init:
* @cache: the #cairo_cache_t to initialise
* @keys_equal: a function to return %TRUE if two keys are equal
* @entry_destroy: destroy notifier for cache entries
* @max_size: the maximum size for this cache
* Returns: the newly created #cairo_cache_t
*
* Creates a new cache using the keys_equal() function to determine
* the equality of entries.
*
* Data is provided to the cache in the form of user-derived version
* of #cairo_cache_entry_t. A cache entry must be able to hold hash
* code, a size, and the key/value pair being stored in the
* cache. Sometimes only the key will be necessary, (as in
* _cairo_cache_lookup()), and in these cases the value portion of the
* entry need not be initialized.
*
* The units for max_size can be chosen by the caller, but should be
* consistent with the units of the size field of cache entries. When
* adding an entry with _cairo_cache_insert() if the total size of
* entries in the cache would exceed max_size then entries will be
* removed at random until the new entry would fit or the cache is
* empty. Then the new entry is inserted.
*
* There are cases in which the automatic removal of entries is
* undesired. If the cache entries have reference counts, then it is a
* simple matter to use the reference counts to ensure that entries
* continue to live even after being ejected from the cache. However,
* in some cases the memory overhead of adding a reference count to
* the entry would be objectionable. In such cases, the
* _cairo_cache_freeze() and _cairo_cache_thaw() calls can be
* used to establish a window during which no automatic removal of
* entries will occur.
**/
cairo_status_t
_cairo_cache_init (cairo_cache_t *cache,
cairo_cache_keys_equal_func_t keys_equal,
cairo_cache_predicate_func_t predicate,
cairo_destroy_func_t entry_destroy,
unsigned long max_size)
{
cache->hash_table = _cairo_hash_table_create (keys_equal);
if (unlikely (cache->hash_table == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (predicate == NULL)
predicate = _cairo_cache_entry_is_non_zero;
cache->predicate = predicate;
cache->entry_destroy = entry_destroy;
cache->max_size = max_size;
cache->size = 0;
cache->freeze_count = 0;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_cache_pluck (void *entry, void *closure)
{
_cairo_cache_remove (closure, entry);
}
/**
* _cairo_cache_fini:
* @cache: a cache to destroy
*
* Immediately destroys the given cache, freeing all resources
* associated with it. As part of this process, the entry_destroy()
* function, (as passed to _cairo_cache_init()), will be called for
* each entry in the cache.
**/
void
_cairo_cache_fini (cairo_cache_t *cache)
{
_cairo_hash_table_foreach (cache->hash_table,
_cairo_cache_pluck,
cache);
assert (cache->size == 0);
_cairo_hash_table_destroy (cache->hash_table);
}
/**
* _cairo_cache_freeze:
* @cache: a cache with some precious entries in it (or about to be
* added)
*
* Disable the automatic ejection of entries from the cache. For as
* long as the cache is "frozen", calls to _cairo_cache_insert() will
* add new entries to the cache regardless of how large the cache
* grows. See _cairo_cache_thaw().
*
* Note: Multiple calls to _cairo_cache_freeze() will stack, in that
* the cache will remain "frozen" until a corresponding number of
* calls are made to _cairo_cache_thaw().
**/
void
_cairo_cache_freeze (cairo_cache_t *cache)
{
assert (cache->freeze_count >= 0);
cache->freeze_count++;
}
/**
* _cairo_cache_thaw:
* @cache: a cache, just after the entries in it have become less
* precious
*
* Cancels the effects of _cairo_cache_freeze().
*
* When a number of calls to _cairo_cache_thaw() is made corresponding
* to the number of calls to _cairo_cache_freeze() the cache will no
* longer be "frozen". If the cache had grown larger than max_size
* while frozen, entries will immediately be ejected (by random) from
* the cache until the cache is smaller than max_size. Also, the
* automatic ejection of entries on _cairo_cache_insert() will resume.
**/
void
_cairo_cache_thaw (cairo_cache_t *cache)
{
assert (cache->freeze_count > 0);
if (--cache->freeze_count == 0)
_cairo_cache_shrink_to_accommodate (cache, 0);
}
/**
* _cairo_cache_lookup:
* @cache: a cache
* @key: the key of interest
* @entry_return: pointer for return value
*
* Performs a lookup in @cache looking for an entry which has a key
* that matches @key, (as determined by the keys_equal() function
* passed to _cairo_cache_init()).
*
* Return value: %TRUE if there is an entry in the cache that matches
* @key, (which will now be in *entry_return). %FALSE otherwise, (in
* which case *entry_return will be %NULL).
**/
void *
_cairo_cache_lookup (cairo_cache_t *cache,
cairo_cache_entry_t *key)
{
return _cairo_hash_table_lookup (cache->hash_table,
(cairo_hash_entry_t *) key);
}
/**
* _cairo_cache_remove_random:
* @cache: a cache
*
* Remove a random entry from the cache.
*
* Return value: %TRUE if an entry was successfully removed.
* %FALSE if there are no entries that can be removed.
**/
static cairo_bool_t
_cairo_cache_remove_random (cairo_cache_t *cache)
{
cairo_cache_entry_t *entry;
entry = _cairo_hash_table_random_entry (cache->hash_table,
cache->predicate);
if (unlikely (entry == NULL))
return FALSE;
_cairo_cache_remove (cache, entry);
return TRUE;
}
/**
* _cairo_cache_shrink_to_accommodate:
* @cache: a cache
* @additional: additional size requested in bytes
*
* If cache is not frozen, eject entries randomly until the size of
* the cache is at least @additional bytes less than
* cache->max_size. That is, make enough room to accommodate a new
* entry of size @additional.
**/
static void
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
unsigned long additional)
{
while (cache->size + additional > cache->max_size) {
if (! _cairo_cache_remove_random (cache))
return;
}
}
/**
* _cairo_cache_insert:
* @cache: a cache
* @entry: an entry to be inserted
*
* Insert @entry into the cache. If an entry exists in the cache with
* a matching key, then the old entry will be removed first, (and the
* entry_destroy() callback will be called on it).
*
* Return value: %CAIRO_STATUS_SUCCESS if successful or
* %CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
**/
cairo_status_t
_cairo_cache_insert (cairo_cache_t *cache,
cairo_cache_entry_t *entry)
{
cairo_status_t status;
if (entry->size && ! cache->freeze_count)
_cairo_cache_shrink_to_accommodate (cache, entry->size);
status = _cairo_hash_table_insert (cache->hash_table,
(cairo_hash_entry_t *) entry);
if (unlikely (status))
return status;
cache->size += entry->size;
return CAIRO_STATUS_SUCCESS;
}
/**
* _cairo_cache_remove:
* @cache: a cache
* @entry: an entry that exists in the cache
*
* Remove an existing entry from the cache.
**/
void
_cairo_cache_remove (cairo_cache_t *cache,
cairo_cache_entry_t *entry)
{
cache->size -= entry->size;
_cairo_hash_table_remove (cache->hash_table,
(cairo_hash_entry_t *) entry);
if (cache->entry_destroy)
cache->entry_destroy (entry);
}
/**
* _cairo_cache_foreach:
* @cache: a cache
* @cache_callback: function to be called for each entry
* @closure: additional argument to be passed to @cache_callback
*
* Call @cache_callback for each entry in the cache, in a
* non-specified order.
**/
void
_cairo_cache_foreach (cairo_cache_t *cache,
cairo_cache_callback_func_t cache_callback,
void *closure)
{
_cairo_hash_table_foreach (cache->hash_table,
cache_callback,
closure);
}
unsigned long
_cairo_hash_string (const char *c)
{
/* This is the djb2 hash. */
unsigned long hash = _CAIRO_HASH_INIT_VALUE;
while (c && *c)
hash = ((hash << 5) + hash) + *c++;
return hash;
}
unsigned long
_cairo_hash_bytes (unsigned long hash,
const void *ptr,
unsigned int length)
{
const uint8_t *bytes = ptr;
/* This is the djb2 hash. */
while (length--)
hash = ((hash << 5) + hash) + *bytes++;
return hash;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,594 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-box-inline.h"
#include "cairo-clip-inline.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static inline int
pot (int v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
static cairo_bool_t
_cairo_clip_contains_rectangle_box (const cairo_clip_t *clip,
const cairo_rectangle_int_t *rect,
const cairo_box_t *box)
{
int i;
/* clip == NULL means no clip, so the clip contains everything */
if (clip == NULL)
return TRUE;
if (_cairo_clip_is_all_clipped (clip))
return FALSE;
/* If we have a non-trivial path, just say no */
if (clip->path)
return FALSE;
if (! _cairo_rectangle_contains_rectangle (&clip->extents, rect))
return FALSE;
if (clip->num_boxes == 0)
return TRUE;
/* Check for a clip-box that wholly contains the rectangle */
for (i = 0; i < clip->num_boxes; i++) {
if (box->p1.x >= clip->boxes[i].p1.x &&
box->p1.y >= clip->boxes[i].p1.y &&
box->p2.x <= clip->boxes[i].p2.x &&
box->p2.y <= clip->boxes[i].p2.y)
{
return TRUE;
}
}
return FALSE;
}
cairo_bool_t
_cairo_clip_contains_box (const cairo_clip_t *clip,
const cairo_box_t *box)
{
cairo_rectangle_int_t rect;
_cairo_box_round_to_rectangle (box, &rect);
return _cairo_clip_contains_rectangle_box(clip, &rect, box);
}
cairo_bool_t
_cairo_clip_contains_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *rect)
{
cairo_box_t box;
box.p1.x = _cairo_fixed_from_int (rect->x);
box.p1.y = _cairo_fixed_from_int (rect->y);
box.p2.x = _cairo_fixed_from_int (rect->x + rect->width);
box.p2.y = _cairo_fixed_from_int (rect->y + rect->height);
return _cairo_clip_contains_rectangle_box (clip, rect, &box);
}
cairo_clip_t *
_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias)
{
cairo_status_t status;
cairo_boxes_t boxes;
_cairo_boxes_init (&boxes);
status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
fill_rule,
antialias,
&boxes);
if (likely (status == CAIRO_STATUS_SUCCESS && boxes.num_boxes))
clip = _cairo_clip_intersect_boxes (clip, &boxes);
else
clip = _cairo_clip_set_all_clipped (clip);
_cairo_boxes_fini (&boxes);
return clip;
}
static cairo_clip_t *
_cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
const cairo_rectangle_int_t *r,
const cairo_box_t *box)
{
cairo_box_t extents_box;
cairo_bool_t changed = FALSE;
int i, j;
if (clip == NULL) {
clip = _cairo_clip_create ();
if (clip == NULL)
return _cairo_clip_set_all_clipped (clip);
}
if (clip->num_boxes == 0) {
clip->boxes = &clip->embedded_box;
clip->boxes[0] = *box;
clip->num_boxes = 1;
if (clip->path == NULL) {
clip->extents = *r;
} else {
if (! _cairo_rectangle_intersect (&clip->extents, r))
clip = _cairo_clip_set_all_clipped (clip);
}
if (clip->path == NULL)
clip->is_region = _cairo_box_is_pixel_aligned (box);
return clip;
}
/* Does the new box wholly subsume the clip? Perform a cheap check
* for the common condition of a single clip rectangle.
*/
if (clip->num_boxes == 1 &&
clip->boxes[0].p1.x >= box->p1.x &&
clip->boxes[0].p1.y >= box->p1.y &&
clip->boxes[0].p2.x <= box->p2.x &&
clip->boxes[0].p2.y <= box->p2.y)
{
return clip;
}
for (i = j = 0; i < clip->num_boxes; i++) {
cairo_box_t *b = &clip->boxes[j];
if (j != i)
*b = clip->boxes[i];
if (box->p1.x > b->p1.x)
b->p1.x = box->p1.x, changed = TRUE;
if (box->p2.x < b->p2.x)
b->p2.x = box->p2.x, changed = TRUE;
if (box->p1.y > b->p1.y)
b->p1.y = box->p1.y, changed = TRUE;
if (box->p2.y < b->p2.y)
b->p2.y = box->p2.y, changed = TRUE;
j += b->p2.x > b->p1.x && b->p2.y > b->p1.y;
}
clip->num_boxes = j;
if (clip->num_boxes == 0)
return _cairo_clip_set_all_clipped (clip);
if (! changed)
return clip;
extents_box = clip->boxes[0];
for (i = 1; i < clip->num_boxes; i++) {
if (clip->boxes[i].p1.x < extents_box.p1.x)
extents_box.p1.x = clip->boxes[i].p1.x;
if (clip->boxes[i].p1.y < extents_box.p1.y)
extents_box.p1.y = clip->boxes[i].p1.y;
if (clip->boxes[i].p2.x > extents_box.p2.x)
extents_box.p2.x = clip->boxes[i].p2.x;
if (clip->boxes[i].p2.y > extents_box.p2.y)
extents_box.p2.y = clip->boxes[i].p2.y;
}
if (clip->path == NULL) {
_cairo_box_round_to_rectangle (&extents_box, &clip->extents);
} else {
cairo_rectangle_int_t extents_rect;
_cairo_box_round_to_rectangle (&extents_box, &extents_rect);
if (! _cairo_rectangle_intersect (&clip->extents, &extents_rect))
return _cairo_clip_set_all_clipped (clip);
}
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
return clip;
}
cairo_clip_t *
_cairo_clip_intersect_box (cairo_clip_t *clip,
const cairo_box_t *box)
{
cairo_rectangle_int_t r;
_cairo_box_round_to_rectangle (box, &r);
if (r.width == 0 || r.height == 0)
return _cairo_clip_set_all_clipped (clip);
return _cairo_clip_intersect_rectangle_box (clip, &r, box);
}
cairo_clip_t *
_cairo_clip_intersect_boxes (cairo_clip_t *clip,
const cairo_boxes_t *boxes)
{
cairo_boxes_t clip_boxes;
cairo_box_t limits;
cairo_rectangle_int_t extents;
if (_cairo_clip_is_all_clipped (clip))
return clip;
if (boxes->num_boxes == 0)
return _cairo_clip_set_all_clipped (clip);
if (boxes->num_boxes == 1)
return _cairo_clip_intersect_box (clip, boxes->chunks.base);
if (clip == NULL)
clip = _cairo_clip_create ();
if (clip->num_boxes) {
_cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes);
if (unlikely (_cairo_boxes_intersect (&clip_boxes, boxes, &clip_boxes))) {
clip = _cairo_clip_set_all_clipped (clip);
goto out;
}
if (clip->boxes != &clip->embedded_box)
free (clip->boxes);
clip->boxes = NULL;
boxes = &clip_boxes;
}
if (boxes->num_boxes == 0) {
clip = _cairo_clip_set_all_clipped (clip);
goto out;
} else if (boxes->num_boxes == 1) {
clip->boxes = &clip->embedded_box;
clip->boxes[0] = boxes->chunks.base[0];
clip->num_boxes = 1;
} else {
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
}
_cairo_boxes_extents (boxes, &limits);
_cairo_box_round_to_rectangle (&limits, &extents);
if (clip->path == NULL)
clip->extents = extents;
else if (! _cairo_rectangle_intersect (&clip->extents, &extents))
clip = _cairo_clip_set_all_clipped (clip);
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
out:
if (boxes == &clip_boxes)
_cairo_boxes_fini (&clip_boxes);
return clip;
}
cairo_clip_t *
_cairo_clip_intersect_rectangle (cairo_clip_t *clip,
const cairo_rectangle_int_t *r)
{
cairo_box_t box;
if (_cairo_clip_is_all_clipped (clip))
return clip;
if (r->width == 0 || r->height == 0)
return _cairo_clip_set_all_clipped (clip);
box.p1.x = _cairo_fixed_from_int (r->x);
box.p1.y = _cairo_fixed_from_int (r->y);
box.p2.x = _cairo_fixed_from_int (r->x + r->width);
box.p2.y = _cairo_fixed_from_int (r->y + r->height);
return _cairo_clip_intersect_rectangle_box (clip, r, &box);
}
struct reduce {
cairo_clip_t *clip;
cairo_box_t limit;
cairo_box_t extents;
cairo_bool_t inside;
cairo_point_t current_point;
cairo_point_t last_move_to;
};
static void
_add_clipped_edge (struct reduce *r,
const cairo_point_t *p1,
const cairo_point_t *p2,
int y1, int y2)
{
cairo_fixed_t x;
x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y1);
if (x < r->extents.p1.x)
r->extents.p1.x = x;
x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y2);
if (x > r->extents.p2.x)
r->extents.p2.x = x;
if (y1 < r->extents.p1.y)
r->extents.p1.y = y1;
if (y2 > r->extents.p2.y)
r->extents.p2.y = y2;
r->inside = TRUE;
}
static void
_add_edge (struct reduce *r,
const cairo_point_t *p1,
const cairo_point_t *p2)
{
int top, bottom;
int top_y, bot_y;
int n;
if (p1->y < p2->y) {
top = p1->y;
bottom = p2->y;
} else {
top = p2->y;
bottom = p1->y;
}
if (bottom < r->limit.p1.y || top > r->limit.p2.y)
return;
if (p1->x > p2->x) {
const cairo_point_t *t = p1;
p1 = p2;
p2 = t;
}
if (p2->x <= r->limit.p1.x || p1->x >= r->limit.p2.x)
return;
for (n = 0; n < r->clip->num_boxes; n++) {
const cairo_box_t *limits = &r->clip->boxes[n];
if (bottom < limits->p1.y || top > limits->p2.y)
continue;
if (p2->x <= limits->p1.x || p1->x >= limits->p2.x)
continue;
if (p1->x >= limits->p1.x && p2->x <= limits->p1.x) {
top_y = top;
bot_y = bottom;
} else {
int p1_y, p2_y;
p1_y = _cairo_edge_compute_intersection_y_for_x (p1, p2,
limits->p1.x);
p2_y = _cairo_edge_compute_intersection_y_for_x (p1, p2,
limits->p2.x);
if (p1_y < p2_y) {
top_y = p1_y;
bot_y = p2_y;
} else {
top_y = p2_y;
bot_y = p1_y;
}
if (top_y < top)
top_y = top;
if (bot_y > bottom)
bot_y = bottom;
}
if (top_y < limits->p1.y)
top_y = limits->p1.y;
if (bot_y > limits->p2.y)
bot_y = limits->p2.y;
if (bot_y > top_y)
_add_clipped_edge (r, p1, p2, top_y, bot_y);
}
}
static cairo_status_t
_reduce_line_to (void *closure,
const cairo_point_t *point)
{
struct reduce *r = closure;
_add_edge (r, &r->current_point, point);
r->current_point = *point;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_reduce_close (void *closure)
{
struct reduce *r = closure;
return _reduce_line_to (r, &r->last_move_to);
}
static cairo_status_t
_reduce_move_to (void *closure,
const cairo_point_t *point)
{
struct reduce *r = closure;
cairo_status_t status;
/* close current subpath */
status = _reduce_close (closure);
/* make sure that the closure represents a degenerate path */
r->current_point = *point;
r->last_move_to = *point;
return status;
}
static cairo_clip_t *
_cairo_clip_reduce_to_boxes (cairo_clip_t *clip)
{
struct reduce r;
cairo_clip_path_t *clip_path;
cairo_status_t status;
return clip;
if (clip->path == NULL)
return clip;
r.clip = clip;
r.extents.p1.x = r.extents.p1.y = INT_MAX;
r.extents.p2.x = r.extents.p2.y = INT_MIN;
r.inside = FALSE;
r.limit.p1.x = _cairo_fixed_from_int (clip->extents.x);
r.limit.p1.y = _cairo_fixed_from_int (clip->extents.y);
r.limit.p2.x = _cairo_fixed_from_int (clip->extents.x + clip->extents.width);
r.limit.p2.y = _cairo_fixed_from_int (clip->extents.y + clip->extents.height);
clip_path = clip->path;
do {
r.current_point.x = 0;
r.current_point.y = 0;
r.last_move_to = r.current_point;
status = _cairo_path_fixed_interpret_flat (&clip_path->path,
_reduce_move_to,
_reduce_line_to,
_reduce_close,
&r,
clip_path->tolerance);
assert (status == CAIRO_STATUS_SUCCESS);
_reduce_close (&r);
} while ((clip_path = clip_path->prev));
if (! r.inside) {
_cairo_clip_path_destroy (clip->path);
clip->path = NULL;
}
return _cairo_clip_intersect_box (clip, &r.extents);
}
cairo_clip_t *
_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *r)
{
cairo_clip_t *copy;
if (_cairo_clip_is_all_clipped (clip))
return (cairo_clip_t *) clip;
if (_cairo_clip_contains_rectangle (clip, r))
return _cairo_clip_intersect_rectangle (NULL, r);
copy = _cairo_clip_copy_intersect_rectangle (clip, r);
if (_cairo_clip_is_all_clipped (copy))
return copy;
return _cairo_clip_reduce_to_boxes (copy);
}
cairo_clip_t *
_cairo_clip_reduce_for_composite (const cairo_clip_t *clip,
cairo_composite_rectangles_t *extents)
{
const cairo_rectangle_int_t *r;
r = extents->is_bounded ? &extents->bounded : &extents->unbounded;
return _cairo_clip_reduce_to_rectangle (clip, r);
}
cairo_clip_t *
_cairo_clip_from_boxes (const cairo_boxes_t *boxes)
{
cairo_box_t extents;
cairo_clip_t *clip = _cairo_clip_create ();
if (clip == NULL)
return _cairo_clip_set_all_clipped (clip);
/* XXX cow-boxes? */
if(boxes->num_boxes == 1) {
clip->boxes = &clip->embedded_box;
clip->boxes[0] = boxes->chunks.base[0];
clip->num_boxes = 1;
} else {
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
}
_cairo_boxes_extents (boxes, &extents);
_cairo_box_round_to_rectangle (&extents, &clip->extents);
return clip;
}

View File

@@ -0,0 +1,83 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_CLIP_INLINE_H
#define CAIRO_CLIP_INLINE_H
#include "cairo-clip-private.h"
static inline cairo_bool_t _cairo_clip_is_all_clipped(const cairo_clip_t *clip)
{
return clip == &__cairo_clip_all;
}
static inline cairo_clip_t *
_cairo_clip_set_all_clipped (cairo_clip_t *clip)
{
_cairo_clip_destroy (clip);
return (cairo_clip_t *) &__cairo_clip_all;
}
static inline cairo_clip_t *
_cairo_clip_copy_intersect_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *r)
{
return _cairo_clip_intersect_rectangle (_cairo_clip_copy (clip), r);
}
static inline cairo_clip_t *
_cairo_clip_copy_intersect_clip (const cairo_clip_t *clip,
const cairo_clip_t *other)
{
return _cairo_clip_intersect_clip (_cairo_clip_copy (clip), other);
}
static inline void
_cairo_clip_steal_boxes (cairo_clip_t *clip, cairo_boxes_t *boxes)
{
_cairo_boxes_init_for_array (boxes, clip->boxes, clip->num_boxes);
clip->boxes = NULL;
clip->num_boxes = 0;
}
static inline void
_cairo_clip_unsteal_boxes (cairo_clip_t *clip, cairo_boxes_t *boxes)
{
clip->boxes = boxes->chunks.base;
clip->num_boxes = boxes->num_boxes;
}
#endif /* CAIRO_CLIP_INLINE_H */

View File

@@ -0,0 +1,156 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-inline.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static cairo_bool_t
can_convert_to_polygon (const cairo_clip_t *clip)
{
cairo_clip_path_t *clip_path = clip->path;
cairo_antialias_t antialias = clip_path->antialias;
while ((clip_path = clip_path->prev) != NULL) {
if (clip_path->antialias != antialias)
return FALSE;
}
return TRUE;
}
cairo_int_status_t
_cairo_clip_get_polygon (const cairo_clip_t *clip,
cairo_polygon_t *polygon,
cairo_fill_rule_t *fill_rule,
cairo_antialias_t *antialias)
{
cairo_status_t status;
cairo_clip_path_t *clip_path;
if (_cairo_clip_is_all_clipped (clip)) {
_cairo_polygon_init (polygon, NULL, 0);
return CAIRO_INT_STATUS_SUCCESS;
}
/* If there is no clip, we need an infinite polygon */
assert (clip && (clip->path || clip->num_boxes));
if (clip->path == NULL) {
*fill_rule = CAIRO_FILL_RULE_WINDING;
*antialias = CAIRO_ANTIALIAS_DEFAULT;
return _cairo_polygon_init_box_array (polygon,
clip->boxes,
clip->num_boxes);
}
/* check that residual is all of the same type/tolerance */
if (! can_convert_to_polygon (clip))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (clip->num_boxes < 2)
_cairo_polygon_init_with_clip (polygon, clip);
else
_cairo_polygon_init_with_clip (polygon, NULL);
clip_path = clip->path;
*fill_rule = clip_path->fill_rule;
*antialias = clip_path->antialias;
status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
clip_path->tolerance,
polygon);
if (unlikely (status))
goto err;
if (clip->num_boxes > 1) {
status = _cairo_polygon_intersect_with_boxes (polygon, fill_rule,
clip->boxes, clip->num_boxes);
if (unlikely (status))
goto err;
}
polygon->limits = NULL;
polygon->num_limits = 0;
while ((clip_path = clip_path->prev) != NULL) {
cairo_polygon_t next;
_cairo_polygon_init (&next, NULL, 0);
status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
clip_path->tolerance,
&next);
if (likely (status == CAIRO_STATUS_SUCCESS))
status = _cairo_polygon_intersect (polygon, *fill_rule,
&next, clip_path->fill_rule);
_cairo_polygon_fini (&next);
if (unlikely (status))
goto err;
*fill_rule = CAIRO_FILL_RULE_WINDING;
}
return CAIRO_STATUS_SUCCESS;
err:
_cairo_polygon_fini (polygon);
return status;
}
cairo_bool_t
_cairo_clip_is_polygon (const cairo_clip_t *clip)
{
if (_cairo_clip_is_all_clipped (clip))
return TRUE;
/* If there is no clip, we need an infinite polygon */
if (clip == NULL)
return FALSE;
if (clip->path == NULL)
return TRUE;
/* check that residual is all of the same type/tolerance */
return can_convert_to_polygon (clip);
}

View File

@@ -0,0 +1,198 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_CLIP_PRIVATE_H
#define CAIRO_CLIP_PRIVATE_H
#include "cairo-types-private.h"
#include "cairo-boxes-private.h"
#include "cairo-error-private.h"
#include "cairo-compiler-private.h"
#include "cairo-error-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-reference-count-private.h"
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
struct _cairo_clip_path {
cairo_reference_count_t ref_count;
cairo_path_fixed_t path;
cairo_fill_rule_t fill_rule;
double tolerance;
cairo_antialias_t antialias;
cairo_clip_path_t *prev;
};
struct _cairo_clip {
cairo_rectangle_int_t extents;
cairo_clip_path_t *path;
cairo_box_t *boxes;
int num_boxes;
cairo_region_t *region;
cairo_bool_t is_region;
cairo_box_t embedded_box;
};
cairo_private cairo_clip_t *
_cairo_clip_create (void);
cairo_private cairo_clip_path_t *
_cairo_clip_path_reference (cairo_clip_path_t *clip_path);
cairo_private void
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
cairo_private void
_cairo_clip_destroy (cairo_clip_t *clip);
cairo_private extern const cairo_clip_t __cairo_clip_all;
cairo_private cairo_clip_t *
_cairo_clip_copy (const cairo_clip_t *clip);
cairo_private cairo_clip_t *
_cairo_clip_copy_region (const cairo_clip_t *clip);
cairo_private cairo_clip_t *
_cairo_clip_copy_path (const cairo_clip_t *clip);
cairo_private cairo_clip_t *
_cairo_clip_translate (cairo_clip_t *clip, int tx, int ty);
cairo_private cairo_clip_t *
_cairo_clip_transform (cairo_clip_t *clip, const cairo_matrix_t *m);
cairo_private cairo_clip_t *
_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty);
cairo_private cairo_bool_t
_cairo_clip_equal (const cairo_clip_t *clip_a,
const cairo_clip_t *clip_b);
cairo_private cairo_clip_t *
_cairo_clip_intersect_rectangle (cairo_clip_t *clip,
const cairo_rectangle_int_t *rectangle);
cairo_private cairo_clip_t *
_cairo_clip_intersect_clip (cairo_clip_t *clip,
const cairo_clip_t *other);
cairo_private cairo_clip_t *
_cairo_clip_intersect_box (cairo_clip_t *clip,
const cairo_box_t *box);
cairo_private cairo_clip_t *
_cairo_clip_intersect_boxes (cairo_clip_t *clip,
const cairo_boxes_t *boxes);
cairo_private cairo_clip_t *
_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
cairo_antialias_t antialias);
cairo_private cairo_clip_t *
_cairo_clip_intersect_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias);
cairo_private const cairo_rectangle_int_t *
_cairo_clip_get_extents (const cairo_clip_t *clip);
cairo_private cairo_surface_t *
_cairo_clip_get_surface (const cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
cairo_private cairo_surface_t *
_cairo_clip_get_image (const cairo_clip_t *clip,
cairo_surface_t *target,
const cairo_rectangle_int_t *extents);
cairo_private cairo_status_t
_cairo_clip_combine_with_surface (const cairo_clip_t *clip,
cairo_surface_t *dst,
int dst_x, int dst_y);
cairo_private cairo_clip_t *
_cairo_clip_from_boxes (const cairo_boxes_t *boxes);
cairo_private cairo_region_t *
_cairo_clip_get_region (const cairo_clip_t *clip);
cairo_private cairo_bool_t
_cairo_clip_is_region (const cairo_clip_t *clip);
cairo_private cairo_clip_t *
_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *r);
cairo_private cairo_clip_t *
_cairo_clip_reduce_for_composite (const cairo_clip_t *clip,
cairo_composite_rectangles_t *extents);
cairo_private cairo_bool_t
_cairo_clip_contains_rectangle (const cairo_clip_t *clip,
const cairo_rectangle_int_t *rect);
cairo_private cairo_bool_t
_cairo_clip_contains_box (const cairo_clip_t *clip,
const cairo_box_t *box);
cairo_private cairo_bool_t
_cairo_clip_contains_extents (const cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents);
cairo_private cairo_rectangle_list_t*
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
cairo_private cairo_rectangle_list_t *
_cairo_rectangle_list_create_in_error (cairo_status_t status);
cairo_private cairo_bool_t
_cairo_clip_is_polygon (const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_clip_get_polygon (const cairo_clip_t *clip,
cairo_polygon_t *polygon,
cairo_fill_rule_t *fill_rule,
cairo_antialias_t *antialias);
#endif /* CAIRO_CLIP_PRIVATE_H */

View File

@@ -0,0 +1,123 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static void
_cairo_clip_extract_region (cairo_clip_t *clip)
{
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
cairo_rectangle_int_t *r = stack_rects;
cairo_bool_t is_region;
int i;
if (clip->num_boxes == 0)
return;
if (clip->num_boxes > ARRAY_LENGTH (stack_rects)) {
r = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_rectangle_int_t));
if (r == NULL){
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return;
}
}
is_region = clip->path == NULL;
for (i = 0; i < clip->num_boxes; i++) {
cairo_box_t *b = &clip->boxes[i];
if (is_region)
is_region =
_cairo_fixed_is_integer (b->p1.x | b->p1.y | b->p2.x | b->p2.y);
r[i].x = _cairo_fixed_integer_floor (b->p1.x);
r[i].y = _cairo_fixed_integer_floor (b->p1.y);
r[i].width = _cairo_fixed_integer_ceil (b->p2.x) - r[i].x;
r[i].height = _cairo_fixed_integer_ceil (b->p2.y) - r[i].y;
}
clip->is_region = is_region;
clip->region = cairo_region_create_rectangles (r, i);
if (r != stack_rects)
free (r);
}
cairo_region_t *
_cairo_clip_get_region (const cairo_clip_t *clip)
{
if (clip == NULL)
return NULL;
if (clip->region == NULL)
_cairo_clip_extract_region ((cairo_clip_t *) clip);
return clip->region;
}
cairo_bool_t
_cairo_clip_is_region (const cairo_clip_t *clip)
{
if (clip == NULL)
return TRUE;
if (clip->is_region)
return TRUE;
/* XXX Geometric reduction? */
if (clip->path)
return FALSE;
if (clip->num_boxes == 0)
return TRUE;
if (clip->region == NULL)
_cairo_clip_extract_region ((cairo_clip_t *) clip);
return clip->is_region;
}

View File

@@ -0,0 +1,240 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
cairo_status_t
_cairo_clip_combine_with_surface (const cairo_clip_t *clip,
cairo_surface_t *dst,
int dst_x, int dst_y)
{
cairo_clip_path_t *copy_path;
cairo_clip_path_t *clip_path;
cairo_clip_t *copy;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
copy = _cairo_clip_copy_with_translation (clip, -dst_x, -dst_y);
copy_path = copy->path;
copy->path = NULL;
if (copy->boxes) {
status = _cairo_surface_paint (dst,
CAIRO_OPERATOR_IN,
&_cairo_pattern_white.base,
copy);
}
clip = NULL;
if (_cairo_clip_is_region (copy))
clip = copy;
clip_path = copy_path;
while (status == CAIRO_STATUS_SUCCESS && clip_path) {
status = _cairo_surface_fill (dst,
CAIRO_OPERATOR_IN,
&_cairo_pattern_white.base,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias,
clip);
clip_path = clip_path->prev;
}
copy->path = copy_path;
_cairo_clip_destroy (copy);
return status;
}
static cairo_status_t
_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
const cairo_box_t *box,
cairo_fixed_t fx,
cairo_fixed_t fy)
{
cairo_status_t status;
status = _cairo_path_fixed_move_to (path, box->p1.x + fx, box->p1.y + fy);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p1.y + fy);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p2.y + fy);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p1.x + fx, box->p2.y + fy);
if (unlikely (status))
return status;
return _cairo_path_fixed_close_path (path);
}
cairo_surface_t *
_cairo_clip_get_surface (const cairo_clip_t *clip,
cairo_surface_t *target,
int *tx, int *ty)
{
cairo_surface_t *surface;
cairo_status_t status;
cairo_clip_t *copy, *region;
cairo_clip_path_t *copy_path, *clip_path;
if (clip->num_boxes) {
cairo_path_fixed_t path;
int i;
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
clip->extents.width,
clip->extents.height,
CAIRO_COLOR_TRANSPARENT);
if (unlikely (surface->status))
return surface;
_cairo_path_fixed_init (&path);
status = CAIRO_STATUS_SUCCESS;
for (i = 0; status == CAIRO_STATUS_SUCCESS && i < clip->num_boxes; i++) {
status = _cairo_path_fixed_add_box (&path, &clip->boxes[i],
-_cairo_fixed_from_int (clip->extents.x),
-_cairo_fixed_from_int (clip->extents.y));
}
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_surface_fill (surface,
CAIRO_OPERATOR_ADD,
&_cairo_pattern_white.base,
&path,
CAIRO_FILL_RULE_WINDING,
1.,
CAIRO_ANTIALIAS_DEFAULT,
NULL);
_cairo_path_fixed_fini (&path);
if (unlikely (status)) {
cairo_surface_destroy (surface);
return _cairo_surface_create_in_error (status);
}
} else {
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
clip->extents.width,
clip->extents.height,
CAIRO_COLOR_WHITE);
if (unlikely (surface->status))
return surface;
}
copy = _cairo_clip_copy_with_translation (clip,
-clip->extents.x,
-clip->extents.y);
copy_path = copy->path;
copy->path = NULL;
region = copy;
if (! _cairo_clip_is_region (copy))
region = _cairo_clip_copy_region (copy);
status = CAIRO_STATUS_SUCCESS;
clip_path = copy_path;
while (status == CAIRO_STATUS_SUCCESS && clip_path) {
status = _cairo_surface_fill (surface,
CAIRO_OPERATOR_IN,
&_cairo_pattern_white.base,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias,
region);
clip_path = clip_path->prev;
}
copy->path = copy_path;
_cairo_clip_destroy (copy);
if (region != copy)
_cairo_clip_destroy (region);
if (unlikely (status)) {
cairo_surface_destroy (surface);
return _cairo_surface_create_in_error (status);
}
*tx = clip->extents.x;
*ty = clip->extents.y;
return surface;
}
cairo_surface_t *
_cairo_clip_get_image (const cairo_clip_t *clip,
cairo_surface_t *target,
const cairo_rectangle_int_t *extents)
{
cairo_surface_t *surface;
cairo_status_t status;
surface = cairo_surface_create_similar_image (target,
CAIRO_FORMAT_A8,
extents->width,
extents->height);
if (unlikely (surface->status))
return surface;
status = _cairo_surface_paint (surface, CAIRO_OPERATOR_SOURCE,
&_cairo_pattern_white.base, NULL);
if (likely (status == CAIRO_STATUS_SUCCESS))
status = _cairo_clip_combine_with_surface (clip, surface,
extents->x, extents->y);
if (unlikely (status)) {
cairo_surface_destroy (surface);
surface = _cairo_surface_create_in_error (status);
}
return surface;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,838 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2009 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Kristian Høgsberg <krh@redhat.com>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-inline.h"
#include "cairo-clip-private.h"
#include "cairo-error-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-pattern-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-region-private.h"
static freed_pool_t clip_path_pool;
static freed_pool_t clip_pool;
const cairo_clip_t __cairo_clip_all;
static cairo_clip_path_t *
_cairo_clip_path_create (cairo_clip_t *clip)
{
cairo_clip_path_t *clip_path;
clip_path = _freed_pool_get (&clip_path_pool);
if (unlikely (clip_path == NULL)) {
clip_path = malloc (sizeof (cairo_clip_path_t));
if (unlikely (clip_path == NULL))
return NULL;
}
CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);
clip_path->prev = clip->path;
clip->path = clip_path;
return clip_path;
}
cairo_clip_path_t *
_cairo_clip_path_reference (cairo_clip_path_t *clip_path)
{
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
_cairo_reference_count_inc (&clip_path->ref_count);
return clip_path;
}
void
_cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
{
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
if (! _cairo_reference_count_dec_and_test (&clip_path->ref_count))
return;
_cairo_path_fixed_fini (&clip_path->path);
if (clip_path->prev != NULL)
_cairo_clip_path_destroy (clip_path->prev);
_freed_pool_put (&clip_path_pool, clip_path);
}
cairo_clip_t *
_cairo_clip_create (void)
{
cairo_clip_t *clip;
clip = _freed_pool_get (&clip_pool);
if (unlikely (clip == NULL)) {
clip = malloc (sizeof (cairo_clip_t));
if (unlikely (clip == NULL))
return NULL;
}
clip->extents = _cairo_unbounded_rectangle;
clip->path = NULL;
clip->boxes = NULL;
clip->num_boxes = 0;
clip->region = NULL;
clip->is_region = FALSE;
return clip;
}
void
_cairo_clip_destroy (cairo_clip_t *clip)
{
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return;
if (clip->path != NULL)
_cairo_clip_path_destroy (clip->path);
if (clip->boxes != &clip->embedded_box)
free (clip->boxes);
cairo_region_destroy (clip->region);
_freed_pool_put (&clip_pool, clip);
}
cairo_clip_t *
_cairo_clip_copy (const cairo_clip_t *clip)
{
cairo_clip_t *copy;
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return (cairo_clip_t *) clip;
copy = _cairo_clip_create ();
if (clip->path)
copy->path = _cairo_clip_path_reference (clip->path);
if (clip->num_boxes) {
if (clip->num_boxes == 1) {
copy->boxes = &copy->embedded_box;
} else {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
}
memcpy (copy->boxes, clip->boxes,
clip->num_boxes * sizeof (cairo_box_t));
copy->num_boxes = clip->num_boxes;
}
copy->extents = clip->extents;
copy->region = cairo_region_reference (clip->region);
copy->is_region = clip->is_region;
return copy;
}
cairo_clip_t *
_cairo_clip_copy_path (const cairo_clip_t *clip)
{
cairo_clip_t *copy;
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return (cairo_clip_t *) clip;
assert (clip->num_boxes);
copy = _cairo_clip_create ();
copy->extents = clip->extents;
if (clip->path)
copy->path = _cairo_clip_path_reference (clip->path);
return copy;
}
cairo_clip_t *
_cairo_clip_copy_region (const cairo_clip_t *clip)
{
cairo_clip_t *copy;
int i;
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return (cairo_clip_t *) clip;
assert (clip->num_boxes);
copy = _cairo_clip_create ();
copy->extents = clip->extents;
if (clip->num_boxes == 1) {
copy->boxes = &copy->embedded_box;
} else {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
}
for (i = 0; i < clip->num_boxes; i++) {
copy->boxes[i].p1.x = _cairo_fixed_floor (clip->boxes[i].p1.x);
copy->boxes[i].p1.y = _cairo_fixed_floor (clip->boxes[i].p1.y);
copy->boxes[i].p2.x = _cairo_fixed_ceil (clip->boxes[i].p2.x);
copy->boxes[i].p2.y = _cairo_fixed_ceil (clip->boxes[i].p2.y);
}
copy->num_boxes = clip->num_boxes;
copy->region = cairo_region_reference (clip->region);
copy->is_region = TRUE;
return copy;
}
cairo_clip_t *
_cairo_clip_intersect_path (cairo_clip_t *clip,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
cairo_clip_path_t *clip_path;
cairo_status_t status;
cairo_rectangle_int_t extents;
cairo_box_t box;
if (_cairo_clip_is_all_clipped (clip))
return clip;
/* catch the empty clip path */
if (_cairo_path_fixed_fill_is_empty (path))
return _cairo_clip_set_all_clipped (clip);
if (_cairo_path_fixed_is_box (path, &box)) {
if (antialias == CAIRO_ANTIALIAS_NONE) {
box.p1.x = _cairo_fixed_round_down (box.p1.x);
box.p1.y = _cairo_fixed_round_down (box.p1.y);
box.p2.x = _cairo_fixed_round_down (box.p2.x);
box.p2.y = _cairo_fixed_round_down (box.p2.y);
}
return _cairo_clip_intersect_box (clip, &box);
}
if (_cairo_path_fixed_fill_is_rectilinear (path))
return _cairo_clip_intersect_rectilinear_path (clip, path,
fill_rule, antialias);
_cairo_path_fixed_approximate_clip_extents (path, &extents);
if (extents.width == 0 || extents.height == 0)
return _cairo_clip_set_all_clipped (clip);
clip = _cairo_clip_intersect_rectangle (clip, &extents);
if (_cairo_clip_is_all_clipped (clip))
return clip;
clip_path = _cairo_clip_path_create (clip);
if (unlikely (clip_path == NULL))
return _cairo_clip_set_all_clipped (clip);
status = _cairo_path_fixed_init_copy (&clip_path->path, path);
if (unlikely (status))
return _cairo_clip_set_all_clipped (clip);
clip_path->fill_rule = fill_rule;
clip_path->tolerance = tolerance;
clip_path->antialias = antialias;
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
return clip;
}
static cairo_clip_t *
_cairo_clip_intersect_clip_path (cairo_clip_t *clip,
const cairo_clip_path_t *clip_path)
{
if (clip_path->prev)
clip = _cairo_clip_intersect_clip_path (clip, clip_path->prev);
return _cairo_clip_intersect_path (clip,
&clip_path->path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias);
}
cairo_clip_t *
_cairo_clip_intersect_clip (cairo_clip_t *clip,
const cairo_clip_t *other)
{
if (_cairo_clip_is_all_clipped (clip))
return clip;
if (other == NULL)
return clip;
if (clip == NULL)
return _cairo_clip_copy (other);
if (_cairo_clip_is_all_clipped (other))
return _cairo_clip_set_all_clipped (clip);
if (! _cairo_rectangle_intersect (&clip->extents, &other->extents))
return _cairo_clip_set_all_clipped (clip);
if (other->num_boxes) {
cairo_boxes_t boxes;
_cairo_boxes_init_for_array (&boxes, other->boxes, other->num_boxes);
clip = _cairo_clip_intersect_boxes (clip, &boxes);
}
if (! _cairo_clip_is_all_clipped (clip)) {
if (other->path) {
if (clip->path == NULL)
clip->path = _cairo_clip_path_reference (other->path);
else
clip = _cairo_clip_intersect_clip_path (clip, other->path);
}
}
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
return clip;
}
cairo_bool_t
_cairo_clip_equal (const cairo_clip_t *clip_a,
const cairo_clip_t *clip_b)
{
const cairo_clip_path_t *cp_a, *cp_b;
/* are both all-clipped or no-clip? */
if (clip_a == clip_b)
return TRUE;
/* or just one of them? */
if (clip_a == NULL || clip_b == NULL ||
_cairo_clip_is_all_clipped (clip_a) ||
_cairo_clip_is_all_clipped (clip_b))
{
return FALSE;
}
/* We have a pair of normal clips, check their contents */
if (clip_a->num_boxes != clip_b->num_boxes)
return FALSE;
if (memcmp (clip_a->boxes, clip_b->boxes,
sizeof (cairo_box_t) * clip_a->num_boxes))
return FALSE;
cp_a = clip_a->path;
cp_b = clip_b->path;
while (cp_a && cp_b) {
if (cp_a == cp_b)
return TRUE;
/* XXX compare reduced polygons? */
if (cp_a->antialias != cp_b->antialias)
return FALSE;
if (cp_a->tolerance != cp_b->tolerance)
return FALSE;
if (cp_a->fill_rule != cp_b->fill_rule)
return FALSE;
if (! _cairo_path_fixed_equal (&cp_a->path,
&cp_b->path))
return FALSE;
cp_a = cp_a->prev;
cp_b = cp_b->prev;
}
return cp_a == NULL && cp_b == NULL;
}
static cairo_clip_t *
_cairo_clip_path_copy_with_translation (cairo_clip_t *clip,
cairo_clip_path_t *other_path,
int fx, int fy)
{
cairo_status_t status;
cairo_clip_path_t *clip_path;
if (other_path->prev != NULL)
clip = _cairo_clip_path_copy_with_translation (clip, other_path->prev,
fx, fy);
if (_cairo_clip_is_all_clipped (clip))
return clip;
clip_path = _cairo_clip_path_create (clip);
if (unlikely (clip_path == NULL))
return _cairo_clip_set_all_clipped (clip);
status = _cairo_path_fixed_init_copy (&clip_path->path,
&other_path->path);
if (unlikely (status))
return _cairo_clip_set_all_clipped (clip);
_cairo_path_fixed_translate (&clip_path->path, fx, fy);
clip_path->fill_rule = other_path->fill_rule;
clip_path->tolerance = other_path->tolerance;
clip_path->antialias = other_path->antialias;
return clip;
}
cairo_clip_t *
_cairo_clip_translate (cairo_clip_t *clip, int tx, int ty)
{
int fx, fy, i;
cairo_clip_path_t *clip_path;
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return clip;
if (tx == 0 && ty == 0)
return clip;
fx = _cairo_fixed_from_int (tx);
fy = _cairo_fixed_from_int (ty);
for (i = 0; i < clip->num_boxes; i++) {
clip->boxes[i].p1.x += fx;
clip->boxes[i].p2.x += fx;
clip->boxes[i].p1.y += fy;
clip->boxes[i].p2.y += fy;
}
clip->extents.x += tx;
clip->extents.y += ty;
if (clip->path == NULL)
return clip;
clip_path = clip->path;
clip->path = NULL;
clip = _cairo_clip_path_copy_with_translation (clip, clip_path, fx, fy);
_cairo_clip_path_destroy (clip_path);
return clip;
}
static cairo_status_t
_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
const cairo_box_t *box)
{
cairo_status_t status;
status = _cairo_path_fixed_move_to (path, box->p1.x, box->p1.y);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p2.x, box->p1.y);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p2.x, box->p2.y);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (path, box->p1.x, box->p2.y);
if (unlikely (status))
return status;
return _cairo_path_fixed_close_path (path);
}
static cairo_status_t
_cairo_path_fixed_init_from_boxes (cairo_path_fixed_t *path,
const cairo_boxes_t *boxes)
{
cairo_status_t status;
const struct _cairo_boxes_chunk *chunk;
int i;
_cairo_path_fixed_init (path);
if (boxes->num_boxes == 0)
return CAIRO_STATUS_SUCCESS;
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
status = _cairo_path_fixed_add_box (path, &chunk->base[i]);
if (unlikely (status)) {
_cairo_path_fixed_fini (path);
return status;
}
}
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_clip_t *
_cairo_clip_intersect_clip_path_transformed (cairo_clip_t *clip,
const cairo_clip_path_t *clip_path,
const cairo_matrix_t *m)
{
cairo_path_fixed_t path;
if (clip_path->prev)
clip = _cairo_clip_intersect_clip_path_transformed (clip,
clip_path->prev,
m);
if (_cairo_path_fixed_init_copy (&path, &clip_path->path))
return _cairo_clip_set_all_clipped (clip);
_cairo_path_fixed_transform (&path, m);
clip = _cairo_clip_intersect_path (clip,
&path,
clip_path->fill_rule,
clip_path->tolerance,
clip_path->antialias);
_cairo_path_fixed_fini (&path);
return clip;
}
cairo_clip_t *
_cairo_clip_transform (cairo_clip_t *clip, const cairo_matrix_t *m)
{
cairo_clip_t *copy;
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return clip;
if (_cairo_matrix_is_translation (m))
return _cairo_clip_translate (clip, m->x0, m->y0);
copy = _cairo_clip_create ();
if (clip->num_boxes) {
cairo_path_fixed_t path;
cairo_boxes_t boxes;
_cairo_boxes_init_for_array (&boxes, clip->boxes, clip->num_boxes);
_cairo_path_fixed_init_from_boxes (&path, &boxes);
_cairo_path_fixed_transform (&path, m);
copy = _cairo_clip_intersect_path (copy, &path,
CAIRO_FILL_RULE_WINDING,
0.1,
CAIRO_ANTIALIAS_DEFAULT);
_cairo_path_fixed_fini (&path);
}
if (clip->path)
copy = _cairo_clip_intersect_clip_path_transformed (copy, clip->path,m);
_cairo_clip_destroy (clip);
return copy;
}
cairo_clip_t *
_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty)
{
cairo_clip_t *copy;
int fx, fy, i;
if (clip == NULL || _cairo_clip_is_all_clipped (clip))
return (cairo_clip_t *)clip;
if (tx == 0 && ty == 0)
return _cairo_clip_copy (clip);
copy = _cairo_clip_create ();
if (copy == NULL)
return _cairo_clip_set_all_clipped (copy);
fx = _cairo_fixed_from_int (tx);
fy = _cairo_fixed_from_int (ty);
if (clip->num_boxes) {
if (clip->num_boxes == 1) {
copy->boxes = &copy->embedded_box;
} else {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
}
for (i = 0; i < clip->num_boxes; i++) {
copy->boxes[i].p1.x = clip->boxes[i].p1.x + fx;
copy->boxes[i].p2.x = clip->boxes[i].p2.x + fx;
copy->boxes[i].p1.y = clip->boxes[i].p1.y + fy;
copy->boxes[i].p2.y = clip->boxes[i].p2.y + fy;
}
copy->num_boxes = clip->num_boxes;
}
copy->extents = clip->extents;
copy->extents.x += tx;
copy->extents.y += ty;
if (clip->path == NULL)
return copy;
return _cairo_clip_path_copy_with_translation (copy, clip->path, fx, fy);
}
cairo_bool_t
_cairo_clip_contains_extents (const cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents)
{
const cairo_rectangle_int_t *rect;
rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
return _cairo_clip_contains_rectangle (clip, rect);
}
void
_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip)
{
int i;
if (clip == NULL) {
fprintf (stream, "no clip\n");
return;
}
if (_cairo_clip_is_all_clipped (clip)) {
fprintf (stream, "clip: all-clipped\n");
return;
}
fprintf (stream, "clip:\n");
fprintf (stream, " extents: (%d, %d) x (%d, %d), is-region? %d",
clip->extents.x, clip->extents.y,
clip->extents.width, clip->extents.height,
clip->is_region);
fprintf (stream, " num_boxes = %d\n", clip->num_boxes);
for (i = 0; i < clip->num_boxes; i++) {
fprintf (stream, " [%d] = (%f, %f), (%f, %f)\n", i,
_cairo_fixed_to_double (clip->boxes[i].p1.x),
_cairo_fixed_to_double (clip->boxes[i].p1.y),
_cairo_fixed_to_double (clip->boxes[i].p2.x),
_cairo_fixed_to_double (clip->boxes[i].p2.y));
}
if (clip->path) {
cairo_clip_path_t *clip_path = clip->path;
do {
fprintf (stream, "path: aa=%d, tolerance=%f, rule=%d: ",
clip_path->antialias,
clip_path->tolerance,
clip_path->fill_rule);
_cairo_debug_print_path (stream, &clip_path->path);
fprintf (stream, "\n");
} while ((clip_path = clip_path->prev) != NULL);
}
}
const cairo_rectangle_int_t *
_cairo_clip_get_extents (const cairo_clip_t *clip)
{
if (clip == NULL)
return &_cairo_unbounded_rectangle;
if (_cairo_clip_is_all_clipped (clip))
return &_cairo_empty_rectangle;
return &clip->extents;
}
const cairo_rectangle_list_t _cairo_rectangles_nil =
{ CAIRO_STATUS_NO_MEMORY, NULL, 0 };
static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
{ CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
static cairo_bool_t
_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
cairo_rectangle_int_t *clip_rect,
cairo_rectangle_t *user_rect)
{
cairo_bool_t is_tight;
double x1 = clip_rect->x;
double y1 = clip_rect->y;
double x2 = clip_rect->x + (int) clip_rect->width;
double y2 = clip_rect->y + (int) clip_rect->height;
_cairo_gstate_backend_to_user_rectangle (gstate,
&x1, &y1, &x2, &y2,
&is_tight);
user_rect->x = x1;
user_rect->y = y1;
user_rect->width = x2 - x1;
user_rect->height = y2 - y1;
return is_tight;
}
cairo_rectangle_list_t *
_cairo_rectangle_list_create_in_error (cairo_status_t status)
{
cairo_rectangle_list_t *list;
if (status == CAIRO_STATUS_NO_MEMORY)
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
if (status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
list = malloc (sizeof (*list));
if (unlikely (list == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
}
list->status = status;
list->rectangles = NULL;
list->num_rectangles = 0;
return list;
}
cairo_rectangle_list_t *
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
{
#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))
cairo_rectangle_list_t *list;
cairo_rectangle_t *rectangles = NULL;
cairo_region_t *region = NULL;
int n_rects = 0;
int i;
if (clip == NULL)
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
if (_cairo_clip_is_all_clipped (clip))
goto DONE;
if (! _cairo_clip_is_region (clip))
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
region = _cairo_clip_get_region (clip);
if (region == NULL)
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
n_rects = cairo_region_num_rectangles (region);
if (n_rects) {
rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
if (unlikely (rectangles == NULL)) {
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
}
for (i = 0; i < n_rects; ++i) {
cairo_rectangle_int_t clip_rect;
cairo_region_get_rectangle (region, i, &clip_rect);
if (! _cairo_clip_int_rect_to_user (gstate,
&clip_rect,
&rectangles[i]))
{
free (rectangles);
return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
}
}
}
DONE:
list = malloc (sizeof (cairo_rectangle_list_t));
if (unlikely (list == NULL)) {
free (rectangles);
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
}
list->status = CAIRO_STATUS_SUCCESS;
list->rectangles = rectangles;
list->num_rectangles = n_rects;
return list;
#undef ERROR_LIST
}
/**
* cairo_rectangle_list_destroy:
* @rectangle_list: a rectangle list, as obtained from cairo_copy_clip_rectangle_list()
*
* Unconditionally frees @rectangle_list and all associated
* references. After this call, the @rectangle_list pointer must not
* be dereferenced.
*
* Since: 1.4
**/
void
cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list)
{
if (rectangle_list == NULL || rectangle_list == &_cairo_rectangles_nil ||
rectangle_list == &_cairo_rectangles_not_representable)
return;
free (rectangle_list->rectangles);
free (rectangle_list);
}
void
_cairo_clip_reset_static_data (void)
{
_freed_pool_reset (&clip_path_pool);
_freed_pool_reset (&clip_pool);
}

View File

@@ -0,0 +1,52 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef CAIRO_COGL_CONTEXT_PRIVATE_H
#define CAIRO_COGL_CONTEXT_PRIVATE_H
#include "cairo-default-context-private.h"
#include "cairo-cogl-private.h"
typedef struct _cairo_cogl_context {
cairo_default_context_t base;
cairo_cogl_device_t *dev;
int path_ctm_age;
cairo_path_fixed_t user_path;
cairo_bool_t path_is_rectangle;
double x, y, width, height;
} cairo_cogl_context_t;
cairo_t *
_cairo_cogl_context_create (void *target);
#endif /* CAIRO_COGL_CONTEXT_PRIVATE_H */

View File

@@ -0,0 +1,822 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
/* so long as we can verify that the ctm doesn't change multiple times
* during the construction of a path we can build a shadow
* #cairo_path_fixed_t in user coordinates that we can use to create a
* hash value for caching tessellations of that path.
*
* We need to hook into all the points where the ctm can be changed
* so we can bump a cr->path_ctm_age counter.
*
* We need to hook into all the points where the path can be modified
* so we can catch the start of a path and reset the cr->path_ctm_age
* counter at that point.
*
* When a draw operation is hit we can then check that the
* path_ctm_age == 0 and if so we create a hash of the path.
*
* We use this hash to lookup a #cairo_cogl_path_meta_t struct which
* may contain tessellated triangles for the path or may just contain
* a count of how many times the path has been re-seen (we only cache
* tessellated triangles if there is evidence that the path is being
* used multiple times because there is a cost involved in allocating
* a separate buffer for the triangles).
*/
#include "cairoint.h"
#include "cairo-cogl-context-private.h"
#include "cairo-freed-pool-private.h"
#include "cairo-arc-private.h"
#include "cairo-path-fixed-private.h"
#include <glib.h>
static freed_pool_t context_pool;
void
_cairo_cogl_context_reset_static_data (void)
{
_freed_pool_reset (&context_pool);
}
static cairo_status_t
_cairo_cogl_context_rectangle_real (cairo_cogl_context_t *cr,
double x, double y,
double width, double height)
{
cairo_status_t status;
status = cr->dev->backend_parent.rectangle (cr, x, y, width, height);
if (unlikely (status))
return status;
return _cairo_cogl_path_fixed_rectangle (&cr->user_path,
_cairo_fixed_from_double (x),
_cairo_fixed_from_double (y),
_cairo_fixed_from_double (width),
_cairo_fixed_from_double (height));
}
/* The idea here is that we have a simplified way of tracking rectangle paths
* because rectangles are perhaps the most common shape drawn with cairo.
*
* Basically we have a speculative store for a rectangle path that doesn't
* need to use the #cairo_path_fixed_t api to describe a rectangle in terms of
* (move_to,rel_line_to,rel_line_to,_rel_line_to,close) because if you profile
* heavy rectangle drawing with Cairo that process can be overly expensive.
*
* If the user asks to add more than just a rectangle to their current path
* then we "flush" any speculative rectangle stored into the current path
* before continuing to append their operations.
*
* In addition to the speculative store cairo-cogl also has a fast-path
* fill_rectangle drawing operation that further aims to minimize the cost
* of drawing rectangles.
*/
static cairo_status_t
_flush_cr_rectangle (cairo_cogl_context_t *cr)
{
if (!cr->path_is_rectangle)
return CAIRO_STATUS_SUCCESS;
cr->path_is_rectangle = FALSE;
return _cairo_cogl_context_rectangle_real (cr, cr->x, cr->y, cr->width, cr->height);
}
static cairo_status_t
_cairo_cogl_context_restore (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.restore (abstract_cr);
}
static cairo_status_t
_cairo_cogl_context_translate (void *abstract_cr, double tx, double ty)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.translate (abstract_cr, tx, ty);
}
static cairo_status_t
_cairo_cogl_context_scale (void *abstract_cr, double sx, double sy)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.scale (abstract_cr, sx, sy);
}
static cairo_status_t
_cairo_cogl_context_rotate (void *abstract_cr, double theta)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.rotate (abstract_cr, theta);
}
static cairo_status_t
_cairo_cogl_context_transform (void *abstract_cr, const cairo_matrix_t *matrix)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.transform (abstract_cr, matrix);
}
static cairo_status_t
_cairo_cogl_context_set_matrix (void *abstract_cr, const cairo_matrix_t *matrix)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.set_matrix (abstract_cr, matrix);
}
static cairo_status_t
_cairo_cogl_context_set_identity_matrix (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
cr->path_ctm_age++;
return cr->dev->backend_parent.set_identity_matrix (abstract_cr);
}
static cairo_status_t
_cairo_cogl_context_new_path (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.new_path (abstract_cr);
if (unlikely (status))
return status;
_cairo_path_fixed_fini (&cr->user_path);
_cairo_path_fixed_init (&cr->user_path);
cr->path_is_rectangle = FALSE;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_cogl_context_new_sub_path (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.new_sub_path (abstract_cr);
if (unlikely (status))
return status;
_cairo_path_fixed_new_sub_path (&cr->user_path);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_cogl_context_move_to (void *abstract_cr, double x, double y)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_fixed_t x_fixed, y_fixed;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.move_to (abstract_cr, x, y);
if (unlikely (status))
return status;
x_fixed = _cairo_fixed_from_double (x);
y_fixed = _cairo_fixed_from_double (y);
return _cairo_path_fixed_move_to (&cr->user_path, x_fixed, y_fixed);
}
static cairo_status_t
_cairo_cogl_context_line_to (void *abstract_cr, double x, double y)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_fixed_t x_fixed, y_fixed;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.line_to (abstract_cr, x, y);
if (unlikely (status))
return status;
x_fixed = _cairo_fixed_from_double (x);
y_fixed = _cairo_fixed_from_double (y);
if (cr->user_path.buf.base.num_ops == 0)
cr->path_ctm_age = 0;
return _cairo_path_fixed_line_to (&cr->user_path, x_fixed, y_fixed);
}
static cairo_status_t
_cairo_cogl_context_curve_to (void *abstract_cr,
double x1, double y1,
double x2, double y2,
double x3, double y3)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_fixed_t x1_fixed, y1_fixed;
cairo_fixed_t x2_fixed, y2_fixed;
cairo_fixed_t x3_fixed, y3_fixed;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.curve_to (abstract_cr, x1, y1, x2, y2, x3, y3);
if (unlikely (status))
return status;
x1_fixed = _cairo_fixed_from_double (x1);
y1_fixed = _cairo_fixed_from_double (y1);
x2_fixed = _cairo_fixed_from_double (x2);
y2_fixed = _cairo_fixed_from_double (y2);
x3_fixed = _cairo_fixed_from_double (x3);
y3_fixed = _cairo_fixed_from_double (y3);
if (cr->user_path.buf.base.num_ops == 0)
cr->path_ctm_age = 0;
return _cairo_path_fixed_curve_to (&cr->user_path,
x1_fixed, y1_fixed,
x2_fixed, y2_fixed,
x3_fixed, y3_fixed);
}
static cairo_status_t
_cairo_cogl_context_arc (void *abstract_cr,
double xc, double yc, double radius,
double angle1, double angle2,
cairo_bool_t forward)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.arc (abstract_cr, xc, yc, radius, angle1, angle2, forward);
if (unlikely (status))
return status;
if (cr->user_path.buf.base.num_ops == 0)
cr->path_ctm_age = 0;
/* Do nothing, successfully, if radius is <= 0 */
if (radius <= 0.0) {
cairo_fixed_t x_fixed, y_fixed;
x_fixed = _cairo_fixed_from_double (xc);
y_fixed = _cairo_fixed_from_double (yc);
status = _cairo_path_fixed_line_to (&cr->user_path, x_fixed, y_fixed);
if (unlikely (status))
return status;
status = _cairo_path_fixed_line_to (&cr->user_path, x_fixed, y_fixed);
if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
}
status = _cairo_cogl_context_line_to (cr,
xc + radius * cos (angle1),
yc + radius * sin (angle1));
if (unlikely (status))
return status;
if (forward)
_cairo_arc_path (&cr->base.base, xc, yc, radius, angle1, angle2);
else
_cairo_arc_path_negative (&cr->base.base, xc, yc, radius, angle1, angle2);
return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
}
static cairo_status_t
_cairo_cogl_context_rel_move_to (void *abstract_cr, double dx, double dy)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_fixed_t dx_fixed, dy_fixed;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.rel_move_to (abstract_cr, dx, dy);
if (unlikely (status))
return status;
dx_fixed = _cairo_fixed_from_double (dx);
dy_fixed = _cairo_fixed_from_double (dy);
return _cairo_path_fixed_rel_move_to (&cr->user_path, dx_fixed, dy_fixed);
}
static cairo_status_t
_cairo_cogl_context_rel_line_to (void *abstract_cr, double dx, double dy)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_fixed_t dx_fixed, dy_fixed;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.rel_line_to (abstract_cr, dx, dy);
if (unlikely (status))
return status;
dx_fixed = _cairo_fixed_from_double (dx);
dy_fixed = _cairo_fixed_from_double (dy);
if (cr->user_path.buf.base.num_ops == 0)
cr->path_ctm_age = 0;
return _cairo_path_fixed_rel_line_to (&cr->user_path, dx_fixed, dy_fixed);
}
static cairo_status_t
_cairo_cogl_context_rel_curve_to (void *abstract_cr,
double dx1, double dy1,
double dx2, double dy2,
double dx3, double dy3)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_fixed_t dx1_fixed, dy1_fixed;
cairo_fixed_t dx2_fixed, dy2_fixed;
cairo_fixed_t dx3_fixed, dy3_fixed;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.rel_curve_to (abstract_cr, dx1, dy1, dx2, dy2, dx3, dy3);
if (unlikely (status))
return status;
dx1_fixed = _cairo_fixed_from_double (dx1);
dy1_fixed = _cairo_fixed_from_double (dy1);
dx2_fixed = _cairo_fixed_from_double (dx2);
dy2_fixed = _cairo_fixed_from_double (dy2);
dx3_fixed = _cairo_fixed_from_double (dx3);
dy3_fixed = _cairo_fixed_from_double (dy3);
if (cr->user_path.buf.base.num_ops == 0)
cr->path_ctm_age = 0;
return _cairo_path_fixed_rel_curve_to (&cr->user_path,
dx1_fixed, dy1_fixed,
dx2_fixed, dy2_fixed,
dx3_fixed, dy3_fixed);
}
#if 0
static cairo_status_t
_cairo_cogl_context_arc_to (void *abstract_cr,
double x1, double y1,
double x2, double y2,
double radius)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.arc_to (abstract_cr, x1, y1, x2, y2, radius);
if (unlikely (status))
return status;
#warning "FIXME"
}
static cairo_status_t
_cairo_cogl_rel_arc_to (void *cr,
double dx1, double dy1,
double dx2, double dy2,
double radius)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.rel_arc_to (abstract_cr, dx1, dy2, dx2, dy2, radius);
if (unlikely (status))
return status;
#warning "FIXME"
}
#endif
static cairo_status_t
_cairo_cogl_context_close_path (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
if (cr->path_is_rectangle) {
status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
status = cr->dev->backend_parent.close_path (abstract_cr);
if (unlikely (status))
return status;
if (cr->user_path.buf.base.num_ops == 0)
cr->path_ctm_age = 0;
return _cairo_path_fixed_close_path (&cr->user_path);
}
static cairo_status_t
_cairo_cogl_context_rectangle (void *abstract_cr,
double x, double y,
double width, double height)
{
cairo_cogl_context_t *cr = abstract_cr;
if (cr->user_path.buf.base.num_ops == 0) {
cr->path_ctm_age = 0;
#if 1
/* XXX: Since drawing rectangles is so common we have a
* fast-path for drawing a single rectangle. */
cr->x = x;
cr->y = y;
cr->width = width;
cr->height = height;
cr->path_is_rectangle = TRUE;
return CAIRO_STATUS_SUCCESS;
#endif
}
if (cr->path_is_rectangle) {
cairo_status_t status = _flush_cr_rectangle (cr);
if (unlikely (status))
return status;
}
return _cairo_cogl_context_rectangle_real (cr, x, y, width, height);
}
/* Since the surface backend drawing operator functions don't get
* passed the current #cairo_t context we don't have a good way
* to get our user-coordinates path into our surface operator
* functions.
*
* For now we use this function to set side band data on the surface
* itself.
*/
static void
_cairo_cogl_surface_set_side_band_state (cairo_cogl_surface_t *surface,
cairo_cogl_context_t *cr)
{
if (cr->path_ctm_age <= 1) {
surface->user_path = &cr->user_path;
surface->ctm = &cr->base.gstate->ctm;
surface->ctm_inverse = &cr->base.gstate->ctm_inverse;
surface->path_is_rectangle = cr->path_is_rectangle;
if (surface->path_is_rectangle) {
surface->path_rectangle_x = cr->x;
surface->path_rectangle_y = cr->y;
surface->path_rectangle_width = cr->width;
surface->path_rectangle_height = cr->height;
}
} else {
surface->user_path = NULL;
surface->path_is_rectangle = FALSE;
}
}
static cairo_status_t
_cairo_cogl_context_fill (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target;
if (cr->path_is_rectangle) {
status = _cairo_cogl_surface_fill_rectangle (cr->base.gstate->target,
cr->base.gstate->op,
cr->base.gstate->source,
cr->x,
cr->y,
cr->width,
cr->height,
&cr->base.gstate->ctm,
cr->base.gstate->clip);
if (status == CAIRO_STATUS_SUCCESS)
goto DONE;
_flush_cr_rectangle (cr);
}
_cairo_cogl_surface_set_side_band_state (surface, cr);
status = cr->dev->backend_parent.fill (abstract_cr);
if (unlikely (status))
return status;
DONE:
_cairo_path_fixed_fini (&cr->user_path);
_cairo_path_fixed_init (&cr->user_path);
cr->path_is_rectangle = FALSE;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_cogl_context_fill_preserve (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target;
_cairo_cogl_surface_set_side_band_state (surface, cr);
status = cr->dev->backend_parent.fill_preserve (abstract_cr);
if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_cogl_context_stroke (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target;
_cairo_cogl_surface_set_side_band_state (surface, cr);
status = cr->dev->backend_parent.stroke (abstract_cr);
if (unlikely (status))
return status;
_cairo_path_fixed_fini (&cr->user_path);
_cairo_path_fixed_init (&cr->user_path);
cr->path_is_rectangle = FALSE;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_cogl_context_stroke_preserve (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target;
_cairo_cogl_surface_set_side_band_state (surface, cr);
status = cr->dev->backend_parent.stroke_preserve (abstract_cr);
if (unlikely (status))
return status;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_cogl_context_clip (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
cairo_status_t status;
status = cr->dev->backend_parent.clip (abstract_cr);
if (unlikely (status))
return status;
_cairo_path_fixed_fini (&cr->user_path);
_cairo_path_fixed_init (&cr->user_path);
cr->path_is_rectangle = FALSE;
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_cogl_context_destroy (void *abstract_cr)
{
cairo_cogl_context_t *cr = abstract_cr;
_cairo_default_context_fini (&cr->base);
_cairo_path_fixed_fini (&cr->user_path);
/* mark the context as invalid to protect against misuse */
cr->base.base.status = CAIRO_STATUS_NULL_POINTER;
_freed_pool_put (&context_pool, cr);
}
/* We want to hook into the frontend of the path construction APIs so
* we can build up a path description in user coordinates instead of
* backend coordinates so that we can recognize user coordinate
* rectangles and so we can hash a user path independent of its
* transform. (With some care to catch unusual cases where the ctm
* changes mid-path) */
cairo_t *
_cairo_cogl_context_create (void *target)
{
cairo_cogl_surface_t *surface = target;
cairo_cogl_context_t *cr;
cairo_status_t status;
cr = _freed_pool_get (&context_pool);
if (unlikely (cr == NULL)) {
cr = malloc (sizeof (cairo_cogl_context_t));
if (unlikely (cr == NULL))
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
status = _cairo_default_context_init (&cr->base, target);
if (unlikely (status)) {
_freed_pool_put (&context_pool, cr);
return _cairo_create_in_error (status);
}
cr->dev = (cairo_cogl_device_t *)surface->base.device;
if (unlikely (cr->dev->backend_vtable_initialized == FALSE)) {
cairo_backend_t *backend = &cr->dev->backend;
memcpy (backend, cr->base.base.backend, sizeof (cairo_backend_t));
memcpy (&cr->dev->backend_parent, cr->base.base.backend, sizeof (cairo_backend_t));
backend->destroy = _cairo_cogl_context_destroy;
backend->restore = _cairo_cogl_context_restore;
backend->translate = _cairo_cogl_context_translate;
backend->scale = _cairo_cogl_context_scale;
backend->rotate = _cairo_cogl_context_rotate;
backend->transform = _cairo_cogl_context_transform;
backend->set_matrix = _cairo_cogl_context_set_matrix;
backend->set_identity_matrix = _cairo_cogl_context_set_identity_matrix;
backend->new_path = _cairo_cogl_context_new_path;
backend->new_sub_path = _cairo_cogl_context_new_sub_path;
backend->move_to = _cairo_cogl_context_move_to;
backend->rel_move_to = _cairo_cogl_context_rel_move_to;
backend->line_to = _cairo_cogl_context_line_to;
backend->rel_line_to = _cairo_cogl_context_rel_line_to;
backend->curve_to = _cairo_cogl_context_curve_to;
backend->rel_curve_to = _cairo_cogl_context_rel_curve_to;
#if 0
backend->arc_to = _cairo_cogl_context_arc_to;
backend->rel_arc_to = _cairo_cogl_context_rel_arc_to;
#endif
backend->close_path = _cairo_cogl_context_close_path;
//backend->arc = _cairo_cogl_context_arc;
backend->rectangle = _cairo_cogl_context_rectangle;
/* Try to automatically catch if any new path APIs are added that mean
* we may need to overload more functions... */
assert (((char *)&backend->path_extents - (char *)&backend->device_to_user_distance)
== (sizeof (void *) * 14));
backend->fill = _cairo_cogl_context_fill;
backend->fill_preserve = _cairo_cogl_context_fill_preserve;
backend->stroke = _cairo_cogl_context_stroke;
backend->stroke_preserve = _cairo_cogl_context_stroke_preserve;
backend->clip = _cairo_cogl_context_clip;
cr->dev->backend_vtable_initialized = TRUE;
}
cr->base.base.backend = &cr->dev->backend;
_cairo_path_fixed_init (&cr->user_path);
cr->path_is_rectangle = FALSE;
return &cr->base.base;
}

View File

@@ -0,0 +1,89 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef CAIRO_COGL_GRADIENT_PRIVATE_H
#define CAIRO_COGL_GRADIENT_PRIVATE_H
#include "cairoint.h"
#include "cairo-pattern-private.h"
#include <cogl/cogl2-experimental.h>
#define CAIRO_COGL_LINEAR_GRADIENT_CACHE_SIZE (1024 * 1024)
typedef enum _cairo_cogl_gradient_compatibility {
CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD = 1<<0,
CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT = 1<<1,
CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT = 1<<2,
CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE = 1<<3
} cairo_cogl_gradient_compatibility_t;
#define CAIRO_COGL_GRADIENT_CAN_EXTEND_ALL (CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD |\
CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT|\
CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT|\
CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE)
typedef struct _cairo_cogl_linear_texture_entry {
cairo_cogl_gradient_compatibility_t compatibility;
CoglTexture *texture;
float translate_x;
float scale_x;
} cairo_cogl_linear_texture_entry_t;
typedef struct _cairo_cogl_linear_gradient {
cairo_cache_entry_t cache_entry;
cairo_reference_count_t ref_count;
GList *textures;
int n_stops;
const cairo_gradient_stop_t *stops;
cairo_gradient_stop_t stops_embedded[1];
} cairo_cogl_linear_gradient_t;
cairo_int_status_t
_cairo_cogl_get_linear_gradient (cairo_cogl_device_t *context,
cairo_extend_t extend_mode,
int n_stops,
const cairo_gradient_stop_t *stops,
cairo_cogl_linear_gradient_t **gradient_out);
cairo_cogl_linear_texture_entry_t *
_cairo_cogl_linear_gradient_texture_for_extend (cairo_cogl_linear_gradient_t *gradient,
cairo_extend_t extend_mode);
cairo_cogl_linear_gradient_t *
_cairo_cogl_linear_gradient_reference (cairo_cogl_linear_gradient_t *gradient);
void
_cairo_cogl_linear_gradient_destroy (cairo_cogl_linear_gradient_t *gradient);
cairo_bool_t
_cairo_cogl_linear_gradient_equal (const void *key_a, const void *key_b);
#endif /* CAIRO_COGL_GRADIENT_PRIVATE_H */

View File

@@ -0,0 +1,642 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
//#include "cairoint.h"
#include "cairo-cogl-private.h"
#include "cairo-cogl-gradient-private.h"
#include "cairo-image-surface-private.h"
#include <cogl/cogl2-experimental.h>
#include <glib.h>
#define DUMP_GRADIENTS_TO_PNG
static unsigned long
_cairo_cogl_linear_gradient_hash (unsigned int n_stops,
const cairo_gradient_stop_t *stops)
{
return _cairo_hash_bytes (n_stops, stops,
sizeof (cairo_gradient_stop_t) * n_stops);
}
static cairo_cogl_linear_gradient_t *
_cairo_cogl_linear_gradient_lookup (cairo_cogl_device_t *ctx,
unsigned long hash,
unsigned int n_stops,
const cairo_gradient_stop_t *stops)
{
cairo_cogl_linear_gradient_t lookup;
lookup.cache_entry.hash = hash,
lookup.n_stops = n_stops;
lookup.stops = stops;
return _cairo_cache_lookup (&ctx->linear_cache, &lookup.cache_entry);
}
cairo_bool_t
_cairo_cogl_linear_gradient_equal (const void *key_a, const void *key_b)
{
const cairo_cogl_linear_gradient_t *a = key_a;
const cairo_cogl_linear_gradient_t *b = key_b;
if (a->n_stops != b->n_stops)
return FALSE;
return memcmp (a->stops, b->stops, a->n_stops * sizeof (cairo_gradient_stop_t)) == 0;
}
cairo_cogl_linear_gradient_t *
_cairo_cogl_linear_gradient_reference (cairo_cogl_linear_gradient_t *gradient)
{
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count));
_cairo_reference_count_inc (&gradient->ref_count);
return gradient;
}
void
_cairo_cogl_linear_gradient_destroy (cairo_cogl_linear_gradient_t *gradient)
{
GList *l;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count));
if (! _cairo_reference_count_dec_and_test (&gradient->ref_count))
return;
for (l = gradient->textures; l; l = l->next) {
cairo_cogl_linear_texture_entry_t *entry = l->data;
cogl_object_unref (entry->texture);
free (entry);
}
g_list_free (gradient->textures);
free (gradient);
}
static int
_cairo_cogl_util_next_p2 (int a)
{
int rval = 1;
while (rval < a)
rval <<= 1;
return rval;
}
static float
get_max_color_component_range (const cairo_color_stop_t *color0, const cairo_color_stop_t *color1)
{
float range;
float max = 0;
range = fabs (color0->red - color1->red);
max = MAX (range, max);
range = fabs (color0->green - color1->green);
max = MAX (range, max);
range = fabs (color0->blue - color1->blue);
max = MAX (range, max);
range = fabs (color0->alpha - color1->alpha);
max = MAX (range, max);
return max;
}
static int
_cairo_cogl_linear_gradient_width_for_stops (cairo_extend_t extend,
unsigned int n_stops,
const cairo_gradient_stop_t *stops)
{
unsigned int n;
float max_texels_per_unit_offset = 0;
float total_offset_range;
/* Find the stop pair demanding the most precision because we are
* interpolating the largest color-component range.
*
* From that we can define the relative sizes of all the other
* stop pairs within our texture and thus the overall size.
*
* To determine the maximum number of texels for a given gap we
* look at the range of colors we are expected to interpolate (so
* long as the stop offsets are not degenerate) and we simply
* assume we want one texel for each unique color value possible
* for a one byte-per-component representation.
* XXX: maybe this is overkill and just allowing 128 levels
* instead of 256 would be enough and then we'd rely on the
* bilinear filtering to give the full range.
*
* XXX: potentially we could try and map offsets to pixels to come
* up with a more precise mapping, but we are aiming to cache
* the gradients so we can't make assumptions about how it will be
* scaled in the future.
*/
for (n = 1; n < n_stops; n++) {
float color_range;
float offset_range;
float texels;
float texels_per_unit_offset;
/* note: degenerate stops don't need to be represented in the
* texture but we want to be sure that solid gaps get at least
* one texel and all other gaps get at least 2 texels.
*/
if (stops[n].offset == stops[n-1].offset)
continue;
color_range = get_max_color_component_range (&stops[n].color, &stops[n-1].color);
if (color_range == 0)
texels = 1;
else
texels = MAX (2, 256.0f * color_range);
/* So how many texels would we need to map over the full [0,1]
* gradient range so this gap would have enough texels? ... */
offset_range = stops[n].offset - stops[n - 1].offset;
texels_per_unit_offset = texels / offset_range;
if (texels_per_unit_offset > max_texels_per_unit_offset)
max_texels_per_unit_offset = texels_per_unit_offset;
}
total_offset_range = fabs (stops[n_stops - 1].offset - stops[0].offset);
return max_texels_per_unit_offset * total_offset_range;
}
/* Aim to create gradient textures without an alpha component so we can avoid
* needing to use blending... */
static CoglPixelFormat
_cairo_cogl_linear_gradient_format_for_stops (cairo_extend_t extend,
unsigned int n_stops,
const cairo_gradient_stop_t *stops)
{
unsigned int n;
/* We have to add extra transparent texels to the end of the gradient to
* handle CAIRO_EXTEND_NONE... */
if (extend == CAIRO_EXTEND_NONE)
return COGL_PIXEL_FORMAT_BGRA_8888_PRE;
for (n = 1; n < n_stops; n++) {
if (stops[n].color.alpha != 1.0)
return COGL_PIXEL_FORMAT_BGRA_8888_PRE;
}
return COGL_PIXEL_FORMAT_BGR_888;
}
static cairo_cogl_gradient_compatibility_t
_cairo_cogl_compatibility_from_extend_mode (cairo_extend_t extend_mode)
{
switch (extend_mode)
{
case CAIRO_EXTEND_NONE:
return CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE;
case CAIRO_EXTEND_PAD:
return CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD;
case CAIRO_EXTEND_REPEAT:
return CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT;
case CAIRO_EXTEND_REFLECT:
return CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT;
}
assert (0); /* not reached */
return CAIRO_EXTEND_NONE;
}
cairo_cogl_linear_texture_entry_t *
_cairo_cogl_linear_gradient_texture_for_extend (cairo_cogl_linear_gradient_t *gradient,
cairo_extend_t extend_mode)
{
GList *l;
cairo_cogl_gradient_compatibility_t compatibility =
_cairo_cogl_compatibility_from_extend_mode (extend_mode);
for (l = gradient->textures; l; l = l->next) {
cairo_cogl_linear_texture_entry_t *entry = l->data;
if (entry->compatibility & compatibility)
return entry;
}
return NULL;
}
static void
color_stop_lerp (const cairo_color_stop_t *c0,
const cairo_color_stop_t *c1,
float factor,
cairo_color_stop_t *dest)
{
/* NB: we always ignore the short members in this file so we don't need to
* worry about initializing them here. */
dest->red = c0->red * (1.0f-factor) + c1->red * factor;
dest->green = c0->green * (1.0f-factor) + c1->green * factor;
dest->blue = c0->blue * (1.0f-factor) + c1->blue * factor;
dest->alpha = c0->alpha * (1.0f-factor) + c1->alpha * factor;
}
static size_t
_cairo_cogl_linear_gradient_size (cairo_cogl_linear_gradient_t *gradient)
{
GList *l;
size_t size = 0;
for (l = gradient->textures; l; l = l->next) {
cairo_cogl_linear_texture_entry_t *entry = l->data;
size += cogl_texture_get_width (entry->texture) * 4;
}
return size;
}
static void
emit_stop (CoglVertexP2C4 **position,
float left,
float right,
const cairo_color_stop_t *left_color,
const cairo_color_stop_t *right_color)
{
CoglVertexP2C4 *p = *position;
guint8 lr = left_color->red * 255;
guint8 lg = left_color->green * 255;
guint8 lb = left_color->blue * 255;
guint8 la = left_color->alpha * 255;
guint8 rr = right_color->red * 255;
guint8 rg = right_color->green * 255;
guint8 rb = right_color->blue * 255;
guint8 ra = right_color->alpha * 255;
p[0].x = left;
p[0].y = 0;
p[0].r = lr; p[0].g = lg; p[0].b = lb; p[0].a = la;
p[1].x = left;
p[1].y = 1;
p[1].r = lr; p[1].g = lg; p[1].b = lb; p[1].a = la;
p[2].x = right;
p[2].y = 1;
p[2].r = rr; p[2].g = rg; p[2].b = rb; p[2].a = ra;
p[3].x = left;
p[3].y = 0;
p[3].r = lr; p[3].g = lg; p[3].b = lb; p[3].a = la;
p[4].x = right;
p[4].y = 1;
p[4].r = rr; p[4].g = rg; p[4].b = rb; p[4].a = ra;
p[5].x = right;
p[5].y = 0;
p[5].r = rr; p[5].g = rg; p[5].b = rb; p[5].a = ra;
*position = &p[6];
}
#ifdef DUMP_GRADIENTS_TO_PNG
static void
dump_gradient_to_png (CoglTexture *texture)
{
cairo_image_surface_t *image = (cairo_image_surface_t *)
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture));
CoglPixelFormat format;
static int gradient_id = 0;
char *gradient_name;
if (image->base.status)
return;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
#else
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
#endif
cogl_texture_get_data (texture,
format,
0,
image->data);
gradient_name = g_strdup_printf ("./gradient%d.png", gradient_id++);
g_print ("writing gradient: %s\n", gradient_name);
cairo_surface_write_to_png ((cairo_surface_t *)image, gradient_name);
g_free (gradient_name);
}
#endif
cairo_int_status_t
_cairo_cogl_get_linear_gradient (cairo_cogl_device_t *device,
cairo_extend_t extend_mode,
int n_stops,
const cairo_gradient_stop_t *stops,
cairo_cogl_linear_gradient_t **gradient_out)
{
unsigned long hash;
cairo_cogl_linear_gradient_t *gradient;
cairo_cogl_linear_texture_entry_t *entry;
cairo_gradient_stop_t *internal_stops;
int stop_offset;
int n_internal_stops;
int n;
cairo_cogl_gradient_compatibility_t compatibilities;
int width;
int left_padding = 0;
cairo_color_stop_t left_padding_color;
int right_padding = 0;
cairo_color_stop_t right_padding_color;
CoglPixelFormat format;
CoglTexture2D *tex;
GError *error = NULL;
int un_padded_width;
CoglHandle offscreen;
cairo_int_status_t status;
int n_quads;
int n_vertices;
float prev;
float right;
CoglVertexP2C4 *vertices;
CoglVertexP2C4 *p;
CoglPrimitive *prim;
hash = _cairo_cogl_linear_gradient_hash (n_stops, stops);
gradient = _cairo_cogl_linear_gradient_lookup (device, hash, n_stops, stops);
if (gradient) {
cairo_cogl_linear_texture_entry_t *entry =
_cairo_cogl_linear_gradient_texture_for_extend (gradient, extend_mode);
if (entry) {
*gradient_out = _cairo_cogl_linear_gradient_reference (gradient);
return CAIRO_INT_STATUS_SUCCESS;
}
}
if (!gradient) {
gradient = malloc (sizeof (cairo_cogl_linear_gradient_t) +
sizeof (cairo_gradient_stop_t) * (n_stops - 1));
if (!gradient)
return CAIRO_INT_STATUS_NO_MEMORY;
CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1);
/* NB: we update the cache_entry size at the end before
* [re]adding it to the cache. */
gradient->cache_entry.hash = hash;
gradient->textures = NULL;
gradient->n_stops = n_stops;
gradient->stops = gradient->stops_embedded;
memcpy (gradient->stops_embedded, stops, sizeof (cairo_gradient_stop_t) * n_stops);
} else
_cairo_cogl_linear_gradient_reference (gradient);
entry = malloc (sizeof (cairo_cogl_linear_texture_entry_t));
if (!entry) {
status = CAIRO_INT_STATUS_NO_MEMORY;
goto BAIL;
}
compatibilities = _cairo_cogl_compatibility_from_extend_mode (extend_mode);
n_internal_stops = n_stops;
stop_offset = 0;
/* We really need stops covering the full [0,1] range for repeat/reflect
* if we want to use sampler REPEAT/MIRROR wrap modes so we may need
* to add some extra stops... */
if (extend_mode == CAIRO_EXTEND_REPEAT || extend_mode == CAIRO_EXTEND_REFLECT)
{
/* If we don't need any extra stops then actually the texture
* will be shareable for repeat and reflect... */
compatibilities = (CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT |
CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT);
if (stops[0].offset != 0) {
n_internal_stops++;
stop_offset++;
}
if (stops[n_stops - 1].offset != 1)
n_internal_stops++;
}
internal_stops = alloca (n_internal_stops * sizeof (cairo_gradient_stop_t));
memcpy (&internal_stops[stop_offset], stops, sizeof (cairo_gradient_stop_t) * n_stops);
/* cairo_color_stop_t values are all unpremultiplied but we need to
* interpolate premultiplied colors so we premultiply all the double
* components now. (skipping any extra stops added for repeat/reflect)
*
* Anothing thing to note is that by premultiplying the colors
* early we'll also reduce the range of colors to interpolate
* which can result in smaller gradient textures.
*/
for (n = stop_offset; n < n_stops; n++) {
cairo_color_stop_t *color = &internal_stops[n].color;
color->red *= color->alpha;
color->green *= color->alpha;
color->blue *= color->alpha;
}
if (n_internal_stops != n_stops)
{
if (extend_mode == CAIRO_EXTEND_REPEAT) {
compatibilities &= ~CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT;
if (stops[0].offset != 0) {
/* what's the wrap-around distance between the user's end-stops? */
double dx = (1.0 - stops[n_stops - 1].offset) + stops[0].offset;
internal_stops[0].offset = 0;
color_stop_lerp (&stops[0].color,
&stops[n_stops - 1].color,
stops[0].offset / dx,
&internal_stops[0].color);
}
if (stops[n_stops - 1].offset != 1) {
internal_stops[n_internal_stops - 1].offset = 1;
internal_stops[n_internal_stops - 1].color = internal_stops[0].color;
}
} else if (extend_mode == CAIRO_EXTEND_REFLECT) {
compatibilities &= ~CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT;
if (stops[0].offset != 0) {
internal_stops[0].offset = 0;
internal_stops[0].color = stops[n_stops - 1].color;
}
if (stops[n_stops - 1].offset != 1) {
internal_stops[n_internal_stops - 1].offset = 1;
internal_stops[n_internal_stops - 1].color = stops[0].color;
}
}
}
stops = internal_stops;
n_stops = n_internal_stops;
width = _cairo_cogl_linear_gradient_width_for_stops (extend_mode, n_stops, stops);
if (extend_mode == CAIRO_EXTEND_PAD) {
/* Here we need to guarantee that the edge texels of our
* texture correspond to the desired padding color so we
* can use CLAMP_TO_EDGE.
*
* For short stop-gaps and especially for degenerate stops
* it's possible that without special consideration the
* user's end stop colors would not be present in our final
* texture.
*
* To handle this we forcibly add two extra padding texels
* at the edges which extend beyond the [0,1] range of the
* gradient itself and we will later report a translate and
* scale transform to compensate for this.
*/
/* XXX: If we consider generating a mipmap for our 1d texture
* at some point then we also need to consider how much
* padding to add to be sure lower mipmap levels still have
* the desired edge color (as opposed to a linear blend with
* other colors of the gradient).
*/
left_padding = 1;
left_padding_color = stops[0].color;
right_padding = 1;
right_padding_color = stops[n_stops - 1].color;
} else if (extend_mode == CAIRO_EXTEND_NONE) {
/* We handle EXTEND_NONE by adding two extra, transparent, texels at
* the ends of the texture and use CLAMP_TO_EDGE.
*
* We add a scale and translate transform so to account for our texels
* extending beyond the [0,1] range. */
left_padding = 1;
left_padding_color.red = 0;
left_padding_color.green = 0;
left_padding_color.blue = 0;
left_padding_color.alpha = 0;
right_padding = 1;
right_padding_color = left_padding_color;
}
/* If we still have stops that don't cover the full [0,1] range
* then we need to define a texture-coordinate scale + translate
* transform to account for that... */
if (stops[n_stops - 1].offset - stops[0].offset < 1) {
float range = stops[n_stops - 1].offset - stops[0].offset;
entry->scale_x = 1.0 / range;
entry->translate_x = -(stops[0].offset * entry->scale_x);
}
width += left_padding + right_padding;
width = _cairo_cogl_util_next_p2 (width);
width = MIN (4096, width); /* lets not go too stupidly big! */
format = _cairo_cogl_linear_gradient_format_for_stops (extend_mode, n_stops, stops);
do {
tex = cogl_texture_2d_new_with_size (device->cogl_context,
width,
1,
format,
&error);
if (!tex)
g_error_free (error);
} while (tex == NULL && width >> 1);
if (!tex) {
status = CAIRO_INT_STATUS_NO_MEMORY;
goto BAIL;
}
entry->texture = COGL_TEXTURE (tex);
entry->compatibility = compatibilities;
un_padded_width = width - left_padding - right_padding;
/* XXX: only when we know the final texture width can we calculate the
* scale and translate factors needed to account for padding... */
if (un_padded_width != width)
entry->scale_x *= (float)un_padded_width / (float)width;
if (left_padding)
entry->translate_x += (entry->scale_x / (float)un_padded_width) * (float)left_padding;
offscreen = cogl_offscreen_new_to_texture (tex);
cogl_push_framebuffer (COGL_FRAMEBUFFER (offscreen));
cogl_ortho (0, width, 1, 0, -1, 100);
cogl_framebuffer_clear4f (COGL_FRAMEBUFFER (offscreen),
COGL_BUFFER_BIT_COLOR,
0, 0, 0, 0);
n_quads = n_stops - 1 + !!left_padding + !!right_padding;
n_vertices = 6 * n_quads;
vertices = alloca (sizeof (CoglVertexP2C4) * n_vertices);
p = vertices;
if (left_padding)
emit_stop (&p, 0, left_padding, &left_padding_color, &left_padding_color);
prev = (float)left_padding;
for (n = 1; n < n_stops; n++) {
right = (float)left_padding + (float)un_padded_width * stops[n].offset;
emit_stop (&p, prev, right, &stops[n-1].color, &stops[n].color);
prev = right;
}
if (right_padding)
emit_stop (&p, prev, width, &right_padding_color, &right_padding_color);
prim = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
n_vertices,
vertices);
/* Just use this as the simplest way to setup a default pipeline... */
cogl_set_source_color4f (0, 0, 0, 0);
cogl_primitive_draw (prim);
cogl_object_unref (prim);
cogl_pop_framebuffer ();
cogl_object_unref (offscreen);
gradient->textures = g_list_prepend (gradient->textures, entry);
gradient->cache_entry.size = _cairo_cogl_linear_gradient_size (gradient);
#ifdef DUMP_GRADIENTS_TO_PNG
dump_gradient_to_png (COGL_TEXTURE (tex));
#endif
#warning "FIXME:"
/* XXX: it seems the documentation of _cairo_cache_insert isn't true - it
* doesn't handle re-adding the same entry gracefully - the cache will
* just keep on growing and then it will start randomly evicting things
* pointlessly */
/* we ignore errors here and just return an uncached gradient */
if (likely (! _cairo_cache_insert (&device->linear_cache, &gradient->cache_entry)))
_cairo_cogl_linear_gradient_reference (gradient);
*gradient_out = gradient;
return CAIRO_INT_STATUS_SUCCESS;
BAIL:
free (entry);
if (gradient)
_cairo_cogl_linear_gradient_destroy (gradient);
return status;
}

View File

@@ -0,0 +1,164 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef CAIRO_COGL_PRIVATE_H
#define CAIRO_COGL_PRIVATE_H
#include "cairo-device-private.h"
#include "cairo-cache-private.h"
#include "cairo-backend-private.h"
#include "cairo-default-context-private.h"
#include "cairo-surface-private.h"
#include <cogl/cogl2-experimental.h>
typedef enum _cairo_cogl_template_type {
CAIRO_COGL_TEMPLATE_TYPE_SOLID,
CAIRO_COGL_TEMPLATE_TYPE_TEXTURE,
CAIRO_COGL_TEMPLATE_TYPE_MASK_SOLID,
CAIRO_COGL_TEMPLATE_TYPE_MASK_TEXTURE,
CAIRO_COGL_TEMPLATE_TYPE_COUNT
} cairo_cogl_template_type;
typedef struct _cairo_cogl_device {
cairo_device_t base;
cairo_bool_t backend_vtable_initialized;
cairo_backend_t backend;
/* We save a copy of all the original backend methods that we override so
* we can chain up...
*/
cairo_backend_t backend_parent;
CoglContext *cogl_context;
CoglTexture *dummy_texture;
/* This is a sparsely filled set of templates because we don't support
* the full range of operators that cairo has. All entries corresponding
* to unsupported operators are NULL.
*
* The CAIRO_OPERATOR_ADD is the operator enum with the highest value that
* we support so we at least cap the size of the array by that.
*
* For each operator we have a template for when we have a solid source
* and another for each texture format that could be used as a source.
*/
CoglPipeline *template_pipelines[CAIRO_OPERATOR_ADD + 1][CAIRO_COGL_TEMPLATE_TYPE_COUNT];
CoglMatrix identity;
/* Caches 1d linear gradient textures */
cairo_cache_t linear_cache;
cairo_cache_t path_fill_staging_cache;
cairo_cache_t path_fill_prim_cache;
cairo_cache_t path_stroke_staging_cache;
cairo_cache_t path_stroke_prim_cache;
} cairo_cogl_device_t;
typedef struct _cairo_cogl_clip_primitives {
cairo_t *clip;
CoglPrimitive **primitives;
} cairo_cogl_clip_primitives_t;
typedef struct _cairo_cogl_surface {
cairo_surface_t base;
CoglPixelFormat cogl_format;
cairo_bool_t ignore_alpha;
/* We currently have 3 basic kinds of Cogl surfaces:
* 1) A light surface simply wrapping a CoglTexture
* 2) A CoglOffscreen framebuffer that implicitly also wraps a CoglTexture
* 3) A CoglOnscreen framebuffer which could potentially be mapped to
* a CoglTexture (e.g. via tfp on X11) but we don't currently do
* that.
*/
CoglTexture *texture;
CoglFramebuffer *framebuffer;
int width;
int height;
GQueue *journal;
CoglAttributeBuffer *buffer_stack;
size_t buffer_stack_size;
size_t buffer_stack_offset;
guint8 *buffer_stack_pointer;
cairo_clip_t *last_clip;
/* A small fifo of recently used cairo_clip_ts paired with CoglPrimitives
* that can be used to mask the stencil buffer. */
GList *clips_fifo;
int n_clip_updates_per_frame;
/* Since the surface backend drawing operator functions don't get
* passed the current cairo_t context we don't have a good way
* to get our user-coordinates path into our surface_fill function.
*
* For now we use our _cairo_cogl_context_fill() wrapper to set this
* side band data on the surface...
*/
cairo_path_fixed_t *user_path;
cairo_matrix_t *ctm;
cairo_matrix_t *ctm_inverse;
cairo_bool_t path_is_rectangle;
double path_rectangle_x;
double path_rectangle_y;
double path_rectangle_width;
double path_rectangle_height;
} cairo_cogl_surface_t;
cairo_status_t
_cairo_cogl_path_fixed_rectangle (cairo_path_fixed_t *path,
cairo_fixed_t x,
cairo_fixed_t y,
cairo_fixed_t width,
cairo_fixed_t height);
cairo_int_status_t
_cairo_cogl_surface_fill_rectangle (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
double x,
double y,
double width,
double height,
cairo_matrix_t *ctm,
const cairo_clip_t *clip);
#endif /* CAIRO_COGL_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef CAIRO_COGL_UTILS_PRIVATE_H
#define CAIRO_COGL_UTILS_PRIVATE_H
#include "cairo-path-fixed-private.h"
#include <cogl/cogl2-experimental.h>
CoglPath *
_cairo_cogl_util_path_from_cairo (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
float tolerance);
int
_cairo_cogl_util_next_p2 (int a);
#define CAIRO_FIXED_ONE_FLOAT ((float)(1 << CAIRO_FIXED_FRAC_BITS))
static inline float
_cairo_cogl_util_fixed_to_float (cairo_fixed_t f)
{
return ((float) f) / CAIRO_FIXED_ONE_FLOAT;
}
#endif /* CAIRO_COGL_UTILS_PRIVATE_H */

View File

@@ -0,0 +1,126 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.og/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
#include "cairoint.h"
#include "cairo-cogl-utils-private.h"
#include <cogl/cogl.h>
#include <glib.h>
static cairo_status_t
_cogl_move_to (void *closure,
const cairo_point_t *point)
{
cogl_path_move_to (closure,
_cairo_cogl_util_fixed_to_float (point->x),
_cairo_cogl_util_fixed_to_float (point->y));
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cogl_line_to (void *closure,
const cairo_point_t *point)
{
cogl_path_line_to (closure,
_cairo_cogl_util_fixed_to_float (point->x),
_cairo_cogl_util_fixed_to_float (point->y));
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cogl_curve_to (void *closure,
const cairo_point_t *p0,
const cairo_point_t *p1,
const cairo_point_t *p2)
{
cogl_path_curve_to (closure,
_cairo_cogl_util_fixed_to_float (p0->x),
_cairo_cogl_util_fixed_to_float (p0->y),
_cairo_cogl_util_fixed_to_float (p1->x),
_cairo_cogl_util_fixed_to_float (p1->y),
_cairo_cogl_util_fixed_to_float (p2->x),
_cairo_cogl_util_fixed_to_float (p2->y));
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cogl_close_path (void *closure)
{
cogl_path_close (closure);
return CAIRO_STATUS_SUCCESS;
}
CoglPath *
_cairo_cogl_util_path_from_cairo (const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
float tolerance)
{
CoglPath *cogl_path = cogl_path_new ();
cairo_status_t status;
if (fill_rule == CAIRO_FILL_RULE_EVEN_ODD)
cogl_path_set_fill_rule (cogl_path, COGL_PATH_FILL_RULE_EVEN_ODD);
else
cogl_path_set_fill_rule (cogl_path, COGL_PATH_FILL_RULE_NON_ZERO);
#ifdef USE_CAIRO_PATH_FLATTENER
/* XXX: rely on cairo to do path flattening, since it seems Cogl's
* curve_to flattening is much slower */
status = _cairo_path_fixed_interpret_flat (path,
_cogl_move_to,
_cogl_line_to,
_cogl_close_path,
cogl_path,
tolerance);
#else
status = _cairo_path_fixed_interpret (path,
_cogl_move_to,
_cogl_line_to,
_cogl_curve_to,
_cogl_close_path,
cogl_path);
#endif
assert (status == CAIRO_STATUS_SUCCESS);
return cogl_path;
}
int
_cairo_cogl_util_next_p2 (int a)
{
int rval = 1;
while (rval < a)
rval <<= 1;
return rval;
}

View File

@@ -0,0 +1,69 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Mozilla Corporation.
*
* Contributor(s):
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef CAIRO_VG_H
#define CAIRO_VG_H
#include "cairo.h"
#if CAIRO_HAS_COGL_SURFACE
#include <cogl/cogl2-experimental.h>
CAIRO_BEGIN_DECLS
cairo_public cairo_device_t *
cairo_cogl_device_create (CoglContext *context);
cairo_public cairo_surface_t *
cairo_cogl_surface_create (cairo_device_t *device,
CoglFramebuffer *framebuffer);
cairo_public CoglFramebuffer *
cairo_cogl_surface_get_framebuffer (cairo_surface_t *surface);
cairo_public CoglTexture *
cairo_cogl_surface_get_texture (cairo_surface_t *surface);
cairo_public void
cairo_cogl_surface_end_frame (cairo_surface_t *surface);
CAIRO_END_DECLS
#else /* CAIRO_HAS_COGL_SURFACE*/
# error Cairo was not compiled with support for the Cogl backend
#endif /* CAIRO_HAS_COGL_SURFACE*/
#endif /* CAIRO_COGL_H */

View File

@@ -0,0 +1,198 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
static cairo_color_t const cairo_color_white = {
1.0, 1.0, 1.0, 1.0,
0xffff, 0xffff, 0xffff, 0xffff
};
static cairo_color_t const cairo_color_black = {
0.0, 0.0, 0.0, 1.0,
0x0, 0x0, 0x0, 0xffff
};
static cairo_color_t const cairo_color_transparent = {
0.0, 0.0, 0.0, 0.0,
0x0, 0x0, 0x0, 0x0
};
static cairo_color_t const cairo_color_magenta = {
1.0, 0.0, 1.0, 1.0,
0xffff, 0x0, 0xffff, 0xffff
};
const cairo_color_t *
_cairo_stock_color (cairo_stock_t stock)
{
switch (stock) {
case CAIRO_STOCK_WHITE:
return &cairo_color_white;
case CAIRO_STOCK_BLACK:
return &cairo_color_black;
case CAIRO_STOCK_TRANSPARENT:
return &cairo_color_transparent;
case CAIRO_STOCK_NUM_COLORS:
default:
ASSERT_NOT_REACHED;
/* If the user can get here somehow, give a color that indicates a
* problem. */
return &cairo_color_magenta;
}
}
/* Convert a double in [0.0, 1.0] to an integer in [0, 65535]
* The conversion is designed to divide the input range into 65536
* equally-sized regions. This is achieved by multiplying by 65536 and
* then special-casing the result of an input value of 1.0 so that it
* maps to 65535 instead of 65536.
*/
uint16_t
_cairo_color_double_to_short (double d)
{
uint32_t i;
i = (uint32_t) (d * 65536);
i -= (i >> 16);
return i;
}
static void
_cairo_color_compute_shorts (cairo_color_t *color)
{
color->red_short = _cairo_color_double_to_short (color->red * color->alpha);
color->green_short = _cairo_color_double_to_short (color->green * color->alpha);
color->blue_short = _cairo_color_double_to_short (color->blue * color->alpha);
color->alpha_short = _cairo_color_double_to_short (color->alpha);
}
void
_cairo_color_init_rgba (cairo_color_t *color,
double red, double green, double blue,
double alpha)
{
color->red = red;
color->green = green;
color->blue = blue;
color->alpha = alpha;
_cairo_color_compute_shorts (color);
}
void
_cairo_color_multiply_alpha (cairo_color_t *color,
double alpha)
{
color->alpha *= alpha;
_cairo_color_compute_shorts (color);
}
void
_cairo_color_get_rgba (cairo_color_t *color,
double *red,
double *green,
double *blue,
double *alpha)
{
*red = color->red;
*green = color->green;
*blue = color->blue;
*alpha = color->alpha;
}
void
_cairo_color_get_rgba_premultiplied (cairo_color_t *color,
double *red,
double *green,
double *blue,
double *alpha)
{
*red = color->red * color->alpha;
*green = color->green * color->alpha;
*blue = color->blue * color->alpha;
*alpha = color->alpha;
}
/* NB: This function works both for unmultiplied and premultiplied colors */
cairo_bool_t
_cairo_color_equal (const cairo_color_t *color_a,
const cairo_color_t *color_b)
{
if (color_a == color_b)
return TRUE;
if (color_a->alpha_short != color_b->alpha_short)
return FALSE;
if (color_a->alpha_short == 0)
return TRUE;
return color_a->red_short == color_b->red_short &&
color_a->green_short == color_b->green_short &&
color_a->blue_short == color_b->blue_short;
}
cairo_bool_t
_cairo_color_stop_equal (const cairo_color_stop_t *color_a,
const cairo_color_stop_t *color_b)
{
if (color_a == color_b)
return TRUE;
return color_a->alpha_short == color_b->alpha_short &&
color_a->red_short == color_b->red_short &&
color_a->green_short == color_b->green_short &&
color_a->blue_short == color_b->blue_short;
}
cairo_content_t
_cairo_color_get_content (const cairo_color_t *color)
{
if (CAIRO_COLOR_IS_OPAQUE (color))
return CAIRO_CONTENT_COLOR;
if (color->red_short == 0 &&
color->green_short == 0 &&
color->blue_short == 0)
{
return CAIRO_CONTENT_ALPHA;
}
return CAIRO_CONTENT_COLOR_ALPHA;
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright © 2008 Chris Wilson
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Chris Wilson
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
/* This fragment implements a comb sort (specifically combsort11) */
#ifndef _HAVE_CAIRO_COMBSORT_NEWGAP
#define _HAVE_CAIRO_COMBSORT_NEWGAP
static inline unsigned int
_cairo_combsort_newgap (unsigned int gap)
{
gap = 10 * gap / 13;
if (gap == 9 || gap == 10)
gap = 11;
if (gap < 1)
gap = 1;
return gap;
}
#endif
#define CAIRO_COMBSORT_DECLARE(NAME, TYPE, CMP) \
static void \
NAME (TYPE *base, unsigned int nmemb) \
{ \
unsigned int gap = nmemb; \
unsigned int i, j; \
int swapped; \
do { \
gap = _cairo_combsort_newgap (gap); \
swapped = gap > 1; \
for (i = 0; i < nmemb-gap ; i++) { \
j = i + gap; \
if (CMP (base[i], base[j]) > 0 ) { \
TYPE tmp; \
tmp = base[i]; \
base[i] = base[j]; \
base[j] = tmp; \
swapped = 1; \
} \
} \
} while (swapped); \
}
#define CAIRO_COMBSORT_DECLARE_WITH_DATA(NAME, TYPE, CMP) \
static void \
NAME (TYPE *base, unsigned int nmemb, void *data) \
{ \
unsigned int gap = nmemb; \
unsigned int i, j; \
int swapped; \
do { \
gap = _cairo_combsort_newgap (gap); \
swapped = gap > 1; \
for (i = 0; i < nmemb-gap ; i++) { \
j = i + gap; \
if (CMP (base[i], base[j], data) > 0 ) { \
TYPE tmp; \
tmp = base[i]; \
base[i] = base[j]; \
base[j] = tmp; \
swapped = 1; \
} \
} \
} while (swapped); \
}

View File

@@ -0,0 +1,246 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2002 University of Southern California
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#ifndef CAIRO_COMPILER_PRIVATE_H
#define CAIRO_COMPILER_PRIVATE_H
#include "cairo.h"
#if HAVE_CONFIG_H
#include "config.h"
#endif
/* Size in bytes of buffer to use off the stack per functions.
* Mostly used by text functions. For larger allocations, they'll
* malloc(). */
#ifndef CAIRO_STACK_BUFFER_SIZE
#define CAIRO_STACK_BUFFER_SIZE (512 * sizeof (int))
#endif
#define CAIRO_STACK_ARRAY_LENGTH(T) (CAIRO_STACK_BUFFER_SIZE / sizeof(T))
/*
* The goal of this block is to define the following macros for
* providing faster linkage to functions in the public API for calls
* from within cairo.
*
* slim_hidden_proto(f)
* slim_hidden_proto_no_warn(f)
*
* Declares `f' as a library internal function and hides the
* function from the global symbol table. This macro must be
* expanded after `f' has been declared with a prototype but before
* any calls to the function are seen by the compiler. The no_warn
* variant inhibits warnings about the return value being unused at
* call sites. The macro works by renaming `f' to an internal name
* in the symbol table and hiding that. As far as cairo internal
* calls are concerned they're calling a library internal function
* and thus don't need to bounce via the PLT.
*
* slim_hidden_def(f)
*
* Exports `f' back to the global symbol table. This macro must be
* expanded right after the function definition and only for symbols
* hidden previously with slim_hidden_proto(). The macro works by
* adding a global entry to the symbol table which points at the
* internal name of `f' created by slim_hidden_proto().
*
* Functions in the public API which aren't called by the library
* don't need to be hidden and re-exported using the slim hidden
* macros.
*/
#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name))
# define slim_hidden_int_name(name) INT_##name
# define slim_hidden_proto1(name, internal) \
extern __typeof (name) name \
__asm__ (slim_hidden_asmname (internal))
# define slim_hidden_def1(name, internal) \
extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \
__attribute__((__alias__(slim_hidden_asmname(internal))))
# define slim_hidden_ulp slim_hidden_ulp1(__USER_LABEL_PREFIX__)
# define slim_hidden_ulp1(x) slim_hidden_ulp2(x)
# define slim_hidden_ulp2(x) #x
# define slim_hidden_asmname(name) slim_hidden_asmname1(name)
# define slim_hidden_asmname1(name) slim_hidden_ulp #name
#else
# define slim_hidden_proto(name) int _cairo_dummy_prototype(void)
# define slim_hidden_proto_no_warn(name) int _cairo_dummy_prototype(void)
# define slim_hidden_def(name) int _cairo_dummy_prototype(void)
#endif
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \
__attribute__((__format__(__printf__, fmt_index, va_index)))
#else
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)
#endif
/* slim_internal.h */
#define CAIRO_HAS_HIDDEN_SYMBOLS 1
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && \
(defined(__ELF__) || defined(__APPLE__)) && \
!defined(__sun)
#define cairo_private_no_warn __attribute__((__visibility__("hidden")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
#define cairo_private_no_warn __hidden
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
#define cairo_private_no_warn
#undef CAIRO_HAS_HIDDEN_SYMBOLS
#endif
#ifndef WARN_UNUSED_RESULT
#define WARN_UNUSED_RESULT
#endif
/* Add attribute(warn_unused_result) if supported */
#define cairo_warn WARN_UNUSED_RESULT
#define cairo_private cairo_private_no_warn cairo_warn
/* This macro allow us to deprecate a function by providing an alias
for the old function name to the new function name. With this
macro, binary compatibility is preserved. The macro only works on
some platforms --- tough.
Meanwhile, new definitions in the public header file break the
source code so that it will no longer link against the old
symbols. Instead it will give a descriptive error message
indicating that the old function has been deprecated by the new
function.
*/
#if __GNUC__ >= 2 && defined(__ELF__)
# define CAIRO_FUNCTION_ALIAS(old, new) \
extern __typeof (new) old \
__asm__ ("" #old) \
__attribute__((__alias__("" #new)))
#else
# define CAIRO_FUNCTION_ALIAS(old, new)
#endif
/*
* Cairo uses the following function attributes in order to improve the
* generated code (effectively by manual inter-procedural analysis).
*
* 'cairo_pure': The function is only allowed to read from its arguments
* and global memory (i.e. following a pointer argument or
* accessing a shared variable). The return value should
* only depend on its arguments, and for an identical set of
* arguments should return the same value.
*
* 'cairo_const': The function is only allowed to read from its arguments.
* It is not allowed to access global memory. The return
* value should only depend its arguments, and for an
* identical set of arguments should return the same value.
* This is currently the most strict function attribute.
*
* Both these function attributes allow gcc to perform CSE and
* constant-folding, with 'cairo_const 'also guaranteeing that pointer contents
* do not change across the function call.
*/
#if __GNUC__ >= 3
#define cairo_pure __attribute__((pure))
#define cairo_const __attribute__((const))
#define cairo_always_inline inline __attribute__((always_inline))
#else
#define cairo_pure
#define cairo_const
#define cairo_always_inline inline
#endif
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
#define likely(expr) (__builtin_expect (!!(expr), 1))
#define unlikely(expr) (__builtin_expect (!!(expr), 0))
#else
#define likely(expr) (expr)
#define unlikely(expr) (expr)
#endif
#ifndef __GNUC__
#undef __attribute__
#define __attribute__(x)
#endif
#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
#define access _access
#define fdopen _fdopen
#define hypot _hypot
#define pclose _pclose
#define popen _popen
#define snprintf _snprintf
#define strdup _strdup
#define unlink _unlink
#define vsnprintf _vsnprintf
#endif
#ifdef _MSC_VER
#ifndef __cplusplus
#undef inline
#define inline __inline
#endif
#endif
#if defined(_MSC_VER) && defined(_M_IX86)
/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together.
The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and
will never be folded into another one. Something like this might eventually
be needed for GCC but it seems fine for now. */
#define CAIRO_ENSURE_UNIQUE \
do { \
char func[] = __FUNCTION__; \
char file[] = __FILE__; \
__asm { \
__asm jmp __internal_skip_line_no \
__asm _emit (__LINE__ & 0xff) \
__asm _emit ((__LINE__>>8) & 0xff) \
__asm _emit ((__LINE__>>16) & 0xff) \
__asm _emit ((__LINE__>>24) & 0xff) \
__asm lea eax, func \
__asm lea eax, file \
__asm __internal_skip_line_no: \
}; \
} while (0)
#else
#define CAIRO_ENSURE_UNIQUE do { } while (0)
#endif
#ifdef __STRICT_ANSI__
#undef inline
#define inline __inline__
#endif
#endif

View File

@@ -0,0 +1,159 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2009 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.u>
*/
#ifndef CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
#define CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
#include "cairo-types-private.h"
#include "cairo-error-private.h"
#include "cairo-pattern-private.h"
CAIRO_BEGIN_DECLS
/* Rectangles that take part in a composite operation.
*
* The source and mask track the extents of the respective patterns in device
* space. The unbounded rectangle is essentially the clip rectangle. And the
* intersection of all is the bounded rectangle, which is the minimum extents
* the operation may require. Whether or not the operation is actually bounded
* is tracked in the is_bounded boolean.
*
*/
struct _cairo_composite_rectangles {
cairo_surface_t *surface;
cairo_operator_t op;
cairo_rectangle_int_t source;
cairo_rectangle_int_t mask;
cairo_rectangle_int_t destination;
cairo_rectangle_int_t bounded; /* source? IN mask? IN unbounded */
cairo_rectangle_int_t unbounded; /* destination IN clip */
uint32_t is_bounded;
cairo_rectangle_int_t source_sample_area;
cairo_rectangle_int_t mask_sample_area;
cairo_pattern_union_t source_pattern;
cairo_pattern_union_t mask_pattern;
const cairo_pattern_t *original_source_pattern;
const cairo_pattern_t *original_mask_pattern;
cairo_clip_t *clip; /* clip will be reduced to the minimal container */
};
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_boxes_t *boxes,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_polygon_t *polygon,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_clip_t *clip,
cairo_bool_t *overlap);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles_t *extents,
const cairo_box_t *box);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents,
const cairo_box_t *box);
cairo_private cairo_bool_t
_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite,
cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_composite_rectangles_add_to_damage (cairo_composite_rectangles_t *composite,
cairo_boxes_t *damage);
cairo_private void
_cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents);
CAIRO_END_DECLS
#endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */

View File

@@ -0,0 +1,500 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2009 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-clip-inline.h"
#include "cairo-error-private.h"
#include "cairo-composite-rectangles-private.h"
#include "cairo-pattern-private.h"
/* A collection of routines to facilitate writing compositors. */
void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents)
{
_cairo_clip_destroy (extents->clip);
}
static void
_cairo_composite_reduce_pattern (const cairo_pattern_t *src,
cairo_pattern_union_t *dst)
{
int tx, ty;
_cairo_pattern_init_static_copy (&dst->base, src);
if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID)
return;
dst->base.filter = _cairo_pattern_analyze_filter (&dst->base, NULL),
tx = ty = 0;
if (_cairo_matrix_is_pixman_translation (&dst->base.matrix,
dst->base.filter,
&tx, &ty))
{
dst->base.matrix.x0 = tx;
dst->base.matrix.y0 = ty;
}
}
static inline cairo_bool_t
_cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip)
{
if (_cairo_clip_is_all_clipped (clip))
return FALSE;
extents->surface = surface;
extents->op = op;
_cairo_surface_get_extents (surface, &extents->destination);
extents->clip = NULL;
extents->unbounded = extents->destination;
if (clip && ! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (clip)))
return FALSE;
extents->bounded = extents->unbounded;
extents->is_bounded = _cairo_operator_bounded_by_either (op);
extents->original_source_pattern = source;
_cairo_composite_reduce_pattern (source, &extents->source_pattern);
_cairo_pattern_get_extents (&extents->source_pattern.base,
&extents->source);
if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
return FALSE;
}
extents->original_mask_pattern = NULL;
extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID;
extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */
extents->mask_pattern.solid.color.alpha_short = 0xffff;
return TRUE;
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface, op, source, clip))
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
extents->mask = extents->destination;
extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
if (_cairo_clip_is_all_clipped (extents->clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (extents->clip)))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
_cairo_pattern_sampled_area (&extents->source_pattern.base,
&extents->bounded,
&extents->source_sample_area);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
const cairo_clip_t *clip)
{
cairo_bool_t ret;
ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
extents->unbounded = extents->bounded;
} else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
if (_cairo_clip_is_all_clipped (extents->clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (extents->clip)))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (! _cairo_rectangle_intersect (&extents->bounded,
_cairo_clip_get_extents (extents->clip)) &&
extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
_cairo_pattern_sampled_area (&extents->source_pattern.base,
&extents->bounded,
&extents->source_sample_area);
if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
_cairo_pattern_sampled_area (&extents->mask_pattern.base,
&extents->bounded,
&extents->mask_sample_area);
if (extents->mask_sample_area.width == 0 ||
extents->mask_sample_area.height == 0) {
_cairo_composite_rectangles_fini (extents);
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
}
return CAIRO_STATUS_SUCCESS;
}
cairo_int_status_t
_cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles_t *extents,
const cairo_box_t *box)
{
cairo_rectangle_int_t rect;
cairo_clip_t *clip;
_cairo_box_round_to_rectangle (box, &rect);
if (rect.x == extents->source.x &&
rect.y == extents->source.y &&
rect.width == extents->source.width &&
rect.height == extents->source.height)
{
return CAIRO_INT_STATUS_SUCCESS;
}
_cairo_rectangle_intersect (&extents->source, &rect);
rect = extents->bounded;
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source) &&
extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (rect.width == extents->bounded.width &&
rect.height == extents->bounded.height)
return CAIRO_INT_STATUS_SUCCESS;
if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
extents->unbounded = extents->bounded;
} else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
clip = extents->clip;
extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
if (clip != extents->clip)
_cairo_clip_destroy (clip);
if (_cairo_clip_is_all_clipped (extents->clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (extents->clip)))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
_cairo_pattern_sampled_area (&extents->source_pattern.base,
&extents->bounded,
&extents->source_sample_area);
if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
_cairo_pattern_sampled_area (&extents->mask_pattern.base,
&extents->bounded,
&extents->mask_sample_area);
if (extents->mask_sample_area.width == 0 ||
extents->mask_sample_area.height == 0)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
return CAIRO_INT_STATUS_SUCCESS;
}
cairo_int_status_t
_cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents,
const cairo_box_t *box)
{
cairo_rectangle_int_t mask;
cairo_clip_t *clip;
_cairo_box_round_to_rectangle (box, &mask);
if (mask.x == extents->mask.x &&
mask.y == extents->mask.y &&
mask.width == extents->mask.width &&
mask.height == extents->mask.height)
{
return CAIRO_INT_STATUS_SUCCESS;
}
_cairo_rectangle_intersect (&extents->mask, &mask);
mask = extents->bounded;
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) &&
extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (mask.width == extents->bounded.width &&
mask.height == extents->bounded.height)
return CAIRO_INT_STATUS_SUCCESS;
if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
extents->unbounded = extents->bounded;
} else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
clip = extents->clip;
extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
if (clip != extents->clip)
_cairo_clip_destroy (clip);
if (_cairo_clip_is_all_clipped (extents->clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (extents->clip)))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
_cairo_pattern_sampled_area (&extents->source_pattern.base,
&extents->bounded,
&extents->source_sample_area);
if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
_cairo_pattern_sampled_area (&extents->mask_pattern.base,
&extents->bounded,
&extents->mask_sample_area);
if (extents->mask_sample_area.width == 0 ||
extents->mask_sample_area.height == 0)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
return CAIRO_INT_STATUS_SUCCESS;
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
cairo_surface_t*surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface, op, source, clip))
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
extents->original_mask_pattern = mask;
_cairo_composite_reduce_pattern (mask, &extents->mask_pattern);
_cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface, op, source, clip))
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
_cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface, op, source, clip))
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
_cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_polygon_t *polygon,
const cairo_clip_t *clip)
{
if (! _cairo_composite_rectangles_init (extents,
surface, op, source, clip))
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
_cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_boxes_t *boxes,
const cairo_clip_t *clip)
{
cairo_box_t box;
if (! _cairo_composite_rectangles_init (extents,
surface, op, source, clip))
{
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
_cairo_boxes_extents (boxes, &box);
_cairo_box_round_to_rectangle (&box, &extents->mask);
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_int_status_t
_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
const cairo_clip_t *clip,
cairo_bool_t *overlap)
{
cairo_status_t status;
if (! _cairo_composite_rectangles_init (extents, surface, op, source, clip))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
/* Computing the exact bbox and the overlap is expensive.
* First perform a cheap test to see if the glyphs are all clipped out.
*/
if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK &&
_cairo_scaled_font_glyph_approximate_extents (scaled_font,
glyphs, num_glyphs,
&extents->mask))
{
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask))
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
glyphs, num_glyphs,
&extents->mask,
overlap);
if (unlikely (status))
return status;
if (overlap && *overlap &&
scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE &&
_cairo_pattern_is_opaque_solid (&extents->source_pattern.base))
{
*overlap = FALSE;
}
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_bool_t
_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite,
cairo_clip_t *clip)
{
cairo_rectangle_int_t extents;
cairo_box_t box;
if (clip == NULL)
return TRUE;
extents = composite->destination;
if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
_cairo_rectangle_intersect (&extents, &composite->source);
if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
_cairo_rectangle_intersect (&extents, &composite->mask);
_cairo_box_from_rectangle (&box, &extents);
return _cairo_clip_contains_box (clip, &box);
}
cairo_int_status_t
_cairo_composite_rectangles_add_to_damage (cairo_composite_rectangles_t *composite,
cairo_boxes_t *damage)
{
cairo_int_status_t status;
int n;
for (n = 0; n < composite->clip->num_boxes; n++) {
status = _cairo_boxes_add (damage,
CAIRO_ANTIALIAS_NONE,
&composite->clip->boxes[n]);
if (unlikely (status))
return status;
}
return CAIRO_INT_STATUS_SUCCESS;
}

View File

@@ -0,0 +1,365 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_COMPOSITOR_PRIVATE_H
#define CAIRO_COMPOSITOR_PRIVATE_H
#include "cairo-composite-rectangles-private.h"
CAIRO_BEGIN_DECLS
typedef struct {
cairo_scaled_font_t *font;
cairo_glyph_t *glyphs;
int num_glyphs;
cairo_bool_t use_mask;
cairo_rectangle_int_t extents;
} cairo_composite_glyphs_info_t;
struct cairo_compositor {
const cairo_compositor_t *delegate;
cairo_warn cairo_int_status_t
(*paint) (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *extents);
cairo_warn cairo_int_status_t
(*mask) (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *extents);
cairo_warn cairo_int_status_t
(*stroke) (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *extents,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias);
cairo_warn cairo_int_status_t
(*fill) (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *extents,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias);
cairo_warn cairo_int_status_t
(*glyphs) (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *extents,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_bool_t overlap);
};
struct cairo_mask_compositor {
cairo_compositor_t base;
cairo_int_status_t (*acquire) (void *surface);
cairo_int_status_t (*release) (void *surface);
cairo_int_status_t (*set_clip_region) (void *surface,
cairo_region_t *clip_region);
cairo_surface_t * (*pattern_to_surface) (cairo_surface_t *dst,
const cairo_pattern_t *pattern,
cairo_bool_t is_mask,
const cairo_rectangle_int_t *extents,
const cairo_rectangle_int_t *sample,
int *src_x, int *src_y);
cairo_int_status_t (*draw_image_boxes) (void *surface,
cairo_image_surface_t *image,
cairo_boxes_t *boxes,
int dx, int dy);
cairo_int_status_t (*copy_boxes) (void *surface,
cairo_surface_t *src,
cairo_boxes_t *boxes,
const cairo_rectangle_int_t *extents,
int dx, int dy);
cairo_int_status_t
(*fill_rectangles) (void *surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_int_t *rectangles,
int num_rects);
cairo_int_status_t
(*fill_boxes) (void *surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_boxes_t *boxes);
cairo_int_status_t
(*check_composite) (const cairo_composite_rectangles_t *extents);
cairo_int_status_t
(*composite) (void *dst,
cairo_operator_t op,
cairo_surface_t *src,
cairo_surface_t *mask,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height);
cairo_int_status_t
(*composite_boxes) (void *surface,
cairo_operator_t op,
cairo_surface_t *source,
cairo_surface_t *mask,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
cairo_boxes_t *boxes,
const cairo_rectangle_int_t *extents);
cairo_int_status_t
(*check_composite_glyphs) (const cairo_composite_rectangles_t *extents,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int *num_glyphs);
cairo_int_status_t
(*composite_glyphs) (void *surface,
cairo_operator_t op,
cairo_surface_t *src,
int src_x,
int src_y,
int dst_x,
int dst_y,
cairo_composite_glyphs_info_t *info);
};
struct cairo_traps_compositor {
cairo_compositor_t base;
cairo_int_status_t
(*acquire) (void *surface);
cairo_int_status_t
(*release) (void *surface);
cairo_int_status_t
(*set_clip_region) (void *surface,
cairo_region_t *clip_region);
cairo_surface_t *
(*pattern_to_surface) (cairo_surface_t *dst,
const cairo_pattern_t *pattern,
cairo_bool_t is_mask,
const cairo_rectangle_int_t *extents,
const cairo_rectangle_int_t *sample,
int *src_x, int *src_y);
cairo_int_status_t (*draw_image_boxes) (void *surface,
cairo_image_surface_t *image,
cairo_boxes_t *boxes,
int dx, int dy);
cairo_int_status_t (*copy_boxes) (void *surface,
cairo_surface_t *src,
cairo_boxes_t *boxes,
const cairo_rectangle_int_t *extents,
int dx, int dy);
cairo_int_status_t
(*fill_boxes) (void *surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_boxes_t *boxes);
cairo_int_status_t
(*check_composite) (const cairo_composite_rectangles_t *extents);
cairo_int_status_t
(*composite) (void *dst,
cairo_operator_t op,
cairo_surface_t *src,
cairo_surface_t *mask,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height);
cairo_int_status_t
(*lerp) (void *_dst,
cairo_surface_t *abstract_src,
cairo_surface_t *abstract_mask,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
unsigned int height);
cairo_int_status_t
(*composite_boxes) (void *surface,
cairo_operator_t op,
cairo_surface_t *source,
cairo_surface_t *mask,
int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
cairo_boxes_t *boxes,
const cairo_rectangle_int_t *extents);
cairo_int_status_t
(*composite_traps) (void *dst,
cairo_operator_t op,
cairo_surface_t *source,
int src_x,
int src_y,
int dst_x,
int dst_y,
const cairo_rectangle_int_t *extents,
cairo_antialias_t antialias,
cairo_traps_t *traps);
cairo_int_status_t
(*composite_tristrip) (void *dst,
cairo_operator_t op,
cairo_surface_t *source,
int src_x,
int src_y,
int dst_x,
int dst_y,
const cairo_rectangle_int_t *extents,
cairo_antialias_t antialias,
cairo_tristrip_t *tristrip);
cairo_int_status_t
(*check_composite_glyphs) (const cairo_composite_rectangles_t *extents,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int *num_glyphs);
cairo_int_status_t
(*composite_glyphs) (void *surface,
cairo_operator_t op,
cairo_surface_t *src,
int src_x,
int src_y,
int dst_x,
int dst_y,
cairo_composite_glyphs_info_t *info);
};
cairo_private extern const cairo_compositor_t __cairo_no_compositor;
cairo_private extern const cairo_compositor_t _cairo_fallback_compositor;
cairo_private void
_cairo_mask_compositor_init (cairo_mask_compositor_t *compositor,
const cairo_compositor_t *delegate);
cairo_private void
_cairo_shape_mask_compositor_init (cairo_compositor_t *compositor,
const cairo_compositor_t *delegate);
cairo_private void
_cairo_traps_compositor_init (cairo_traps_compositor_t *compositor,
const cairo_compositor_t *delegate);
cairo_private cairo_int_status_t
_cairo_compositor_paint (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_compositor_mask (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_compositor_stroke (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_compositor_fill (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip);
cairo_private cairo_int_status_t
_cairo_compositor_glyphs (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip);
CAIRO_END_DECLS
#endif /* CAIRO_COMPOSITOR_PRIVATE_H */

View File

@@ -0,0 +1,268 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-compositor-private.h"
#include "cairo-damage-private.h"
#include "cairo-error-private.h"
cairo_int_status_t
_cairo_compositor_paint (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_composite_rectangles_init_for_paint (&extents, surface,
op, source,
clip);
if (unlikely (status))
return status;
do {
while (compositor->paint == NULL)
compositor = compositor->delegate;
status = compositor->paint (compositor, &extents);
compositor = compositor->delegate;
} while (status == CAIRO_INT_STATUS_UNSUPPORTED);
if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
__FUNCTION__,
extents.unbounded.x, extents.unbounded.y,
extents.unbounded.width, extents.unbounded.height));
surface->damage = _cairo_damage_add_rectangle (surface->damage,
&extents.unbounded);
}
_cairo_composite_rectangles_fini (&extents);
return status;
}
cairo_int_status_t
_cairo_compositor_mask (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_pattern_t *mask,
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_composite_rectangles_init_for_mask (&extents, surface,
op, source, mask,
clip);
if (unlikely (status))
return status;
do {
while (compositor->mask == NULL)
compositor = compositor->delegate;
status = compositor->mask (compositor, &extents);
compositor = compositor->delegate;
} while (status == CAIRO_INT_STATUS_UNSUPPORTED);
if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
__FUNCTION__,
extents.unbounded.x, extents.unbounded.y,
extents.unbounded.width, extents.unbounded.height));
surface->damage = _cairo_damage_add_rectangle (surface->damage,
&extents.unbounded);
}
_cairo_composite_rectangles_fini (&extents);
return status;
}
cairo_int_status_t
_cairo_compositor_stroke (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (_cairo_pen_vertices_needed (tolerance, style->line_width/2, ctm) <= 1)
return CAIRO_INT_STATUS_NOTHING_TO_DO;
status = _cairo_composite_rectangles_init_for_stroke (&extents, surface,
op, source,
path, style, ctm,
clip);
if (unlikely (status))
return status;
do {
while (compositor->stroke == NULL)
compositor = compositor->delegate;
status = compositor->stroke (compositor, &extents,
path, style, ctm, ctm_inverse,
tolerance, antialias);
compositor = compositor->delegate;
} while (status == CAIRO_INT_STATUS_UNSUPPORTED);
if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
__FUNCTION__,
extents.unbounded.x, extents.unbounded.y,
extents.unbounded.width, extents.unbounded.height));
surface->damage = _cairo_damage_add_rectangle (surface->damage,
&extents.unbounded);
}
_cairo_composite_rectangles_fini (&extents);
return status;
}
cairo_int_status_t
_cairo_compositor_fill (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias,
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_composite_rectangles_init_for_fill (&extents, surface,
op, source, path,
clip);
if (unlikely (status))
return status;
do {
while (compositor->fill == NULL)
compositor = compositor->delegate;
status = compositor->fill (compositor, &extents,
path, fill_rule, tolerance, antialias);
compositor = compositor->delegate;
} while (status == CAIRO_INT_STATUS_UNSUPPORTED);
if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
__FUNCTION__,
extents.unbounded.x, extents.unbounded.y,
extents.unbounded.width, extents.unbounded.height));
surface->damage = _cairo_damage_add_rectangle (surface->damage,
&extents.unbounded);
}
_cairo_composite_rectangles_fini (&extents);
return status;
}
cairo_int_status_t
_cairo_compositor_glyphs (const cairo_compositor_t *compositor,
cairo_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip)
{
cairo_composite_rectangles_t extents;
cairo_bool_t overlap;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_composite_rectangles_init_for_glyphs (&extents, surface,
op, source,
scaled_font,
glyphs, num_glyphs,
clip, &overlap);
if (unlikely (status))
return status;
do {
while (compositor->glyphs == NULL)
compositor = compositor->delegate;
status = compositor->glyphs (compositor, &extents,
scaled_font, glyphs, num_glyphs, overlap);
compositor = compositor->delegate;
} while (status == CAIRO_INT_STATUS_UNSUPPORTED);
if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
__FUNCTION__,
extents.unbounded.x, extents.unbounded.y,
extents.unbounded.width, extents.unbounded.height));
surface->damage = _cairo_damage_add_rectangle (surface->damage,
&extents.unbounded);
}
_cairo_composite_rectangles_fini (&extents);
return status;
}

View File

@@ -0,0 +1,80 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Intel Corporation
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_CONTOUR_INLINE_H
#define CAIRO_CONTOUR_INLINE_H
#include "cairo-contour-private.h"
CAIRO_BEGIN_DECLS
static inline cairo_int_status_t
_cairo_contour_add_point (cairo_contour_t *contour,
const cairo_point_t *point)
{
struct _cairo_contour_chain *tail = contour->tail;
if (unlikely (tail->num_points == tail->size_points))
return __cairo_contour_add_point (contour, point);
tail->points[tail->num_points++] = *point;
return CAIRO_INT_STATUS_SUCCESS;
}
static inline cairo_point_t *
_cairo_contour_first_point (cairo_contour_t *c)
{
return &c->chain.points[0];
}
static inline cairo_point_t *
_cairo_contour_last_point (cairo_contour_t *c)
{
return &c->tail->points[c->tail->num_points-1];
}
static inline void
_cairo_contour_remove_last_point (cairo_contour_t *contour)
{
if (contour->chain.num_points == 0)
return;
if (--contour->tail->num_points == 0)
__cairo_contour_remove_last_chain (contour);
}
CAIRO_END_DECLS
#endif /* CAIRO_CONTOUR_INLINE_H */

View File

@@ -0,0 +1,124 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Intel Corporation
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_CONTOUR_PRIVATE_H
#define CAIRO_CONTOUR_PRIVATE_H
#include "cairo-types-private.h"
#include "cairo-compiler-private.h"
#include "cairo-error-private.h"
#include "cairo-list-private.h"
#include <stdio.h>
CAIRO_BEGIN_DECLS
/* A contour is simply a closed chain of points that divide the infinite plane
* into inside and outside. Each contour is a simple polygon, that is it
* contains no holes or self-intersections, but maybe either concave or convex.
*/
struct _cairo_contour_chain {
cairo_point_t *points;
int num_points, size_points;
struct _cairo_contour_chain *next;
};
struct _cairo_contour_iter {
cairo_point_t *point;
cairo_contour_chain_t *chain;
};
struct _cairo_contour {
cairo_list_t next;
int direction;
cairo_contour_chain_t chain, *tail;
cairo_point_t embedded_points[64];
};
/* Initial definition of a shape is a set of contours (some representing holes) */
struct _cairo_shape {
cairo_list_t contours;
};
typedef struct _cairo_shape cairo_shape_t;
#if 0
cairo_private cairo_status_t
_cairo_shape_init_from_polygon (cairo_shape_t *shape,
const cairo_polygon_t *polygon);
cairo_private cairo_status_t
_cairo_shape_reduce (cairo_shape_t *shape, double tolerance);
#endif
cairo_private void
_cairo_contour_init (cairo_contour_t *contour,
int direction);
cairo_private cairo_int_status_t
__cairo_contour_add_point (cairo_contour_t *contour,
const cairo_point_t *point);
cairo_private void
_cairo_contour_simplify (cairo_contour_t *contour, double tolerance);
cairo_private void
_cairo_contour_reverse (cairo_contour_t *contour);
cairo_private cairo_int_status_t
_cairo_contour_add (cairo_contour_t *dst,
const cairo_contour_t *src);
cairo_private cairo_int_status_t
_cairo_contour_add_reversed (cairo_contour_t *dst,
const cairo_contour_t *src);
cairo_private void
__cairo_contour_remove_last_chain (cairo_contour_t *contour);
cairo_private void
_cairo_contour_reset (cairo_contour_t *contour);
cairo_private void
_cairo_contour_fini (cairo_contour_t *contour);
cairo_private void
_cairo_debug_print_contour (FILE *file, cairo_contour_t *contour);
CAIRO_END_DECLS
#endif /* CAIRO_CONTOUR_PRIVATE_H */

View File

@@ -0,0 +1,456 @@
/*
* Copyright © 2004 Carl Worth
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2008 Chris Wilson
* Copyright © 2011 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Carl Worth
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Chris Wilson <chris@chris-wilson.co.uk>
*/
typedef unsigned long long uint64_t;
#include "cairoint.h"
#include "cairo-error-private.h"
#include "cairo-freelist-private.h"
#include "cairo-combsort-inline.h"
#include "cairo-contour-inline.h"
#include "cairo-contour-private.h"
void
_cairo_contour_init (cairo_contour_t *contour,
int direction)
{
contour->direction = direction;
contour->chain.points = contour->embedded_points;
contour->chain.next = NULL;
contour->chain.num_points = 0;
contour->chain.size_points = ARRAY_LENGTH (contour->embedded_points);
contour->tail = &contour->chain;
}
cairo_int_status_t
__cairo_contour_add_point (cairo_contour_t *contour,
const cairo_point_t *point)
{
cairo_contour_chain_t *tail = contour->tail;
cairo_contour_chain_t *next;
assert (tail->next == NULL);
next = _cairo_malloc_ab_plus_c (tail->size_points*2,
sizeof (cairo_point_t),
sizeof (cairo_contour_chain_t));
if (unlikely (next == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
next->size_points = tail->size_points*2;
next->num_points = 1;
next->points = (cairo_point_t *)(next+1);
next->next = NULL;
tail->next = next;
contour->tail = next;
next->points[0] = *point;
return CAIRO_INT_STATUS_SUCCESS;
}
static void
first_inc (cairo_contour_t *contour,
cairo_point_t **p,
cairo_contour_chain_t **chain)
{
if (*p == (*chain)->points + (*chain)->num_points) {
assert ((*chain)->next);
*chain = (*chain)->next;
*p = &(*chain)->points[0];
} else
++*p;
}
static void
last_dec (cairo_contour_t *contour,
cairo_point_t **p,
cairo_contour_chain_t **chain)
{
if (*p == (*chain)->points) {
cairo_contour_chain_t *prev;
assert (*chain != &contour->chain);
for (prev = &contour->chain; prev->next != *chain; prev = prev->next)
;
*chain = prev;
*p = &(*chain)->points[(*chain)->num_points-1];
} else
--*p;
}
void
_cairo_contour_reverse (cairo_contour_t *contour)
{
cairo_contour_chain_t *first_chain, *last_chain;
cairo_point_t *first, *last;
contour->direction = -contour->direction;
if (contour->chain.num_points <= 1)
return;
first_chain = &contour->chain;
last_chain = contour->tail;
first = &first_chain->points[0];
last = &last_chain->points[last_chain->num_points-1];
while (first != last) {
cairo_point_t p;
p = *first;
*first = *last;
*last = p;
first_inc (contour, &first, &first_chain);
last_dec (contour, &last, &last_chain);
}
}
cairo_int_status_t
_cairo_contour_add (cairo_contour_t *dst,
const cairo_contour_t *src)
{
const cairo_contour_chain_t *chain;
cairo_int_status_t status;
int i;
for (chain = &src->chain; chain; chain = chain->next) {
for (i = 0; i < chain->num_points; i++) {
status = _cairo_contour_add_point (dst, &chain->points[i]);
if (unlikely (status))
return status;
}
}
return CAIRO_INT_STATUS_SUCCESS;
}
static inline cairo_bool_t
iter_next (cairo_contour_iter_t *iter)
{
if (iter->point == &iter->chain->points[iter->chain->size_points-1]) {
iter->chain = iter->chain->next;
if (iter->chain == NULL)
return FALSE;
iter->point = &iter->chain->points[0];
return TRUE;
} else {
iter->point++;
return TRUE;
}
}
static cairo_bool_t
iter_equal (const cairo_contour_iter_t *i1,
const cairo_contour_iter_t *i2)
{
return i1->chain == i2->chain && i1->point == i2->point;
}
static void
iter_init (cairo_contour_iter_t *iter, cairo_contour_t *contour)
{
iter->chain = &contour->chain;
iter->point = &contour->chain.points[0];
}
static void
iter_init_last (cairo_contour_iter_t *iter, cairo_contour_t *contour)
{
iter->chain = contour->tail;
iter->point = &contour->tail->points[contour->tail->num_points-1];
}
static const cairo_contour_chain_t *prev_const_chain(const cairo_contour_t *contour,
const cairo_contour_chain_t *chain)
{
const cairo_contour_chain_t *prev;
if (chain == &contour->chain)
return NULL;
for (prev = &contour->chain; prev->next != chain; prev = prev->next)
;
return prev;
}
cairo_int_status_t
_cairo_contour_add_reversed (cairo_contour_t *dst,
const cairo_contour_t *src)
{
const cairo_contour_chain_t *last;
cairo_int_status_t status;
int i;
if (src->chain.num_points == 0)
return CAIRO_INT_STATUS_SUCCESS;
for (last = src->tail; last; last = prev_const_chain (src, last)) {
for (i = last->num_points-1; i >= 0; i--) {
status = _cairo_contour_add_point (dst, &last->points[i]);
if (unlikely (status))
return status;
}
}
return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_uint64_t
point_distance_sq (const cairo_point_t *p1,
const cairo_point_t *p2)
{
int32_t dx = p1->x - p2->x;
int32_t dy = p1->y - p2->y;
return _cairo_int64_add(_cairo_int32x32_64_mul (dx, dx), _cairo_int32x32_64_mul (dy, dy));
}
#define DELETED(p) ((p)->x == INT_MIN && (p)->y == INT_MAX)
#define MARK_DELETED(p) ((p)->x = INT_MIN, (p)->y = INT_MAX)
static cairo_bool_t
_cairo_contour_simplify_chain (cairo_contour_t *contour, const double tolerance,
const cairo_contour_iter_t *first,
const cairo_contour_iter_t *last)
{
cairo_contour_iter_t iter, furthest;
uint64_t max_error;
int x0, y0;
int nx, ny;
int count;
iter = *first;
iter_next (&iter);
if (iter_equal (&iter, last))
return FALSE;
x0 = first->point->x;
y0 = first->point->y;
nx = last->point->y - y0;
ny = x0 - last->point->x;
count = 0;
max_error = 0;
do {
cairo_point_t *p = iter.point;
if (! DELETED(p)) {
uint64_t d = (uint64_t)nx * (x0 - p->x) + (uint64_t)ny * (y0 - p->y);
if (d * d > max_error) {
max_error = d * d;
furthest = iter;
}
count++;
}
iter_next (&iter);
} while (! iter_equal (&iter, last));
if (count == 0)
return FALSE;
if (max_error > tolerance * ((uint64_t)nx * nx + (uint64_t)ny * ny)) {
cairo_bool_t simplified;
simplified = FALSE;
simplified |= _cairo_contour_simplify_chain (contour, tolerance,
first, &furthest);
simplified |= _cairo_contour_simplify_chain (contour, tolerance,
&furthest, last);
return simplified;
} else {
iter = *first;
iter_next (&iter);
do {
MARK_DELETED (iter.point);
iter_next (&iter);
} while (! iter_equal (&iter, last));
return TRUE;
}
}
void
_cairo_contour_simplify (cairo_contour_t *contour, double tolerance)
{
cairo_contour_chain_t *chain;
cairo_point_t *last = NULL;
cairo_contour_iter_t iter, furthest;
cairo_bool_t simplified;
uint64_t max = 0;
int i;
if (contour->chain.num_points <= 2)
return;
tolerance = tolerance * CAIRO_FIXED_ONE;
tolerance *= tolerance;
/* stage 1: vertex reduction */
for (chain = &contour->chain; chain; chain = chain->next) {
for (i = 0; i < chain->num_points; i++) {
if (last == NULL ||
_cairo_uint64_to_double(point_distance_sq (last, &chain->points[i])) > tolerance) {
last = &chain->points[i];
} else {
MARK_DELETED (&chain->points[i]);
}
}
}
/* stage2: polygon simplification using Douglas-Peucker */
simplified = FALSE;
do {
last = &contour->chain.points[0];
iter_init (&furthest, contour);
max = 0;
for (chain = &contour->chain; chain; chain = chain->next) {
for (i = 0; i < chain->num_points; i++) {
uint64_t d;
if (DELETED (&chain->points[i]))
continue;
d = point_distance_sq (last, &chain->points[i]);
if (d > max) {
furthest.chain = chain;
furthest.point = &chain->points[i];
max = d;
}
}
}
assert (max);
simplified = FALSE;
iter_init (&iter, contour);
simplified |= _cairo_contour_simplify_chain (contour, tolerance,
&iter, &furthest);
iter_init_last (&iter, contour);
if (! iter_equal (&furthest, &iter))
simplified |= _cairo_contour_simplify_chain (contour, tolerance,
&furthest, &iter);
} while (simplified);
iter_init (&iter, contour);
for (chain = &contour->chain; chain; chain = chain->next) {
int num_points = chain->num_points;
chain->num_points = 0;
for (i = 0; i < num_points; i++) {
if (! DELETED(&chain->points[i])) {
if (iter.point != &chain->points[i])
*iter.point = chain->points[i];
iter.chain->num_points++;
iter_next (&iter);
}
}
}
if (iter.chain) {
cairo_contour_chain_t *next;
for (chain = iter.chain->next; chain; chain = next) {
next = chain->next;
free (chain);
}
iter.chain->next = NULL;
contour->tail = iter.chain;
}
}
void
_cairo_contour_reset (cairo_contour_t *contour)
{
_cairo_contour_fini (contour);
_cairo_contour_init (contour, contour->direction);
}
void
_cairo_contour_fini (cairo_contour_t *contour)
{
cairo_contour_chain_t *chain, *next;
for (chain = contour->chain.next; chain; chain = next) {
next = chain->next;
free (chain);
}
}
void
_cairo_debug_print_contour (FILE *file, cairo_contour_t *contour)
{
cairo_contour_chain_t *chain;
int num_points, size_points;
int i;
num_points = 0;
size_points = 0;
for (chain = &contour->chain; chain; chain = chain->next) {
num_points += chain->num_points;
size_points += chain->size_points;
}
fprintf (file, "contour: direction=%d, num_points=%d / %d\n",
contour->direction, num_points, size_points);
num_points = 0;
for (chain = &contour->chain; chain; chain = chain->next) {
for (i = 0; i < chain->num_points; i++) {
fprintf (file, " [%d] = (%f, %f)\n",
num_points++,
_cairo_fixed_to_double (chain->points[i].x),
_cairo_fixed_to_double (chain->points[i].y));
}
}
}
void
__cairo_contour_remove_last_chain (cairo_contour_t *contour)
{
cairo_contour_chain_t *chain;
if (contour->tail == &contour->chain)
return;
for (chain = &contour->chain; chain->next != contour->tail; chain = chain->next)
;
free (contour->tail);
contour->tail = chain;
chain->next = NULL;
}

View File

@@ -0,0 +1,85 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Chris Wilson
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#ifndef CAIRO_DAMAGE_PRIVATE_H
#define CAIRO_DAMAGE_PRIVATE_H
#include "cairo-types-private.h"
#include <pixman.h>
CAIRO_BEGIN_DECLS
struct _cairo_damage {
cairo_status_t status;
cairo_region_t *region;
int dirty, remain;
struct _cairo_damage_chunk {
struct _cairo_damage_chunk *next;
cairo_box_t *base;
int count;
int size;
} chunks, *tail;
cairo_box_t boxes[32];
};
cairo_private cairo_damage_t *
_cairo_damage_create (void);
cairo_private cairo_damage_t *
_cairo_damage_create_in_error (cairo_status_t status);
cairo_private cairo_damage_t *
_cairo_damage_add_box (cairo_damage_t *damage,
const cairo_box_t *box);
cairo_private cairo_damage_t *
_cairo_damage_add_rectangle (cairo_damage_t *damage,
const cairo_rectangle_int_t *rect);
cairo_private cairo_damage_t *
_cairo_damage_add_region (cairo_damage_t *damage,
const cairo_region_t *region);
cairo_private cairo_damage_t *
_cairo_damage_reduce (cairo_damage_t *damage);
cairo_private void
_cairo_damage_destroy (cairo_damage_t *damage);
CAIRO_END_DECLS
#endif /* CAIRO_DAMAGE_PRIVATE_H */

View File

@@ -0,0 +1,241 @@
/*
* Copyright © 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Chris Wilson
*
* Contributor(s):
* Chris Wilson <chris@chris-wilson.co.uk>
*/
#include "cairoint.h"
#include "cairo-damage-private.h"
#include "cairo-region-private.h"
static const cairo_damage_t __cairo_damage__nil = { CAIRO_STATUS_NO_MEMORY };
cairo_damage_t *
_cairo_damage_create_in_error (cairo_status_t status)
{
_cairo_error_throw (status);
return (cairo_damage_t *) &__cairo_damage__nil;
}
cairo_damage_t *
_cairo_damage_create (void)
{
cairo_damage_t *damage;
damage = malloc (sizeof (*damage));
if (unlikely (damage == NULL)) {
_cairo_error_throw(CAIRO_STATUS_NO_MEMORY);
return (cairo_damage_t *) &__cairo_damage__nil;
}
damage->status = CAIRO_STATUS_SUCCESS;
damage->region = NULL;
damage->dirty = 0;
damage->tail = &damage->chunks;
damage->chunks.base = damage->boxes;
damage->chunks.size = ARRAY_LENGTH(damage->boxes);
damage->chunks.count = 0;
damage->chunks.next = NULL;
damage->remain = damage->chunks.size;
return damage;
}
void
_cairo_damage_destroy (cairo_damage_t *damage)
{
struct _cairo_damage_chunk *chunk, *next;
if (damage == (cairo_damage_t *) &__cairo_damage__nil)
return;
for (chunk = damage->chunks.next; chunk != NULL; chunk = next) {
next = chunk->next;
free (chunk);
}
cairo_region_destroy (damage->region);
free (damage);
}
static cairo_damage_t *
_cairo_damage_add_boxes(cairo_damage_t *damage,
const cairo_box_t *boxes,
int count)
{
struct _cairo_damage_chunk *chunk;
int n, size;
TRACE ((stderr, "%s x%d\n", __FUNCTION__, count));
if (damage == NULL)
damage = _cairo_damage_create ();
if (damage->status)
return damage;
damage->dirty += count;
n = count;
if (n > damage->remain)
n = damage->remain;
memcpy (damage->tail->base + damage->tail->count, boxes,
n * sizeof (cairo_box_t));
count -= n;
damage->tail->count += n;
damage->remain -= n;
if (count == 0)
return damage;
size = 2 * damage->tail->size;
if (size < count)
size = (count + 64) & ~63;
chunk = malloc (sizeof (*chunk) + sizeof (cairo_box_t) * size);
if (unlikely (chunk == NULL)) {
_cairo_damage_destroy (damage);
return (cairo_damage_t *) &__cairo_damage__nil;
}
chunk->next = NULL;
chunk->base = (cairo_box_t *) (chunk + 1);
chunk->size = size;
chunk->count = count;
damage->tail->next = chunk;
damage->tail = chunk;
memcpy (damage->tail->base, boxes + n,
count * sizeof (cairo_box_t));
damage->remain = size - count;
return damage;
}
cairo_damage_t *
_cairo_damage_add_box(cairo_damage_t *damage,
const cairo_box_t *box)
{
TRACE ((stderr, "%s: (%d, %d),(%d, %d)\n", __FUNCTION__,
box->p1.x, box->p1.y, box->p2.x, box->p2.y));
return _cairo_damage_add_boxes(damage, box, 1);
}
cairo_damage_t *
_cairo_damage_add_rectangle(cairo_damage_t *damage,
const cairo_rectangle_int_t *r)
{
cairo_box_t box;
TRACE ((stderr, "%s: (%d, %d)x(%d, %d)\n", __FUNCTION__,
r->x, r->y, r->width, r->height));
box.p1.x = r->x;
box.p1.y = r->y;
box.p2.x = r->x + r->width;
box.p2.y = r->y + r->height;
return _cairo_damage_add_boxes(damage, &box, 1);
}
cairo_damage_t *
_cairo_damage_add_region (cairo_damage_t *damage,
const cairo_region_t *region)
{
cairo_box_t *boxes;
int nbox;
TRACE ((stderr, "%s\n", __FUNCTION__));
boxes = _cairo_region_get_boxes (region, &nbox);
return _cairo_damage_add_boxes(damage, boxes, nbox);
}
cairo_damage_t *
_cairo_damage_reduce (cairo_damage_t *damage)
{
cairo_box_t *free_boxes = NULL;
cairo_box_t *boxes, *b;
struct _cairo_damage_chunk *chunk, *last;
TRACE ((stderr, "%s: dirty=%d\n", __FUNCTION__,
damage ? damage->dirty : -1));
if (damage == NULL || damage->status || !damage->dirty)
return damage;
if (damage->region) {
cairo_region_t *region;
region = damage->region;
damage->region = NULL;
damage = _cairo_damage_add_region (damage, region);
cairo_region_destroy (region);
if (unlikely (damage->status))
return damage;
}
boxes = damage->tail->base;
if (damage->dirty > damage->tail->size) {
boxes = free_boxes = malloc (damage->dirty * sizeof (cairo_box_t));
if (unlikely (boxes == NULL)) {
_cairo_damage_destroy (damage);
return (cairo_damage_t *) &__cairo_damage__nil;
}
b = boxes;
last = NULL;
} else {
b = boxes + damage->tail->count;
last = damage->tail;
}
for (chunk = &damage->chunks; chunk != last; chunk = chunk->next) {
memcpy (b, chunk->base, chunk->count * sizeof (cairo_box_t));
b += chunk->count;
}
damage->region = _cairo_region_create_from_boxes (boxes, damage->dirty);
free (free_boxes);
if (unlikely (damage->region->status)) {
_cairo_damage_destroy (damage);
return (cairo_damage_t *) &__cairo_damage__nil;
}
damage->dirty = 0;
return damage;
}

View File

@@ -0,0 +1,304 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#include "cairoint.h"
#include "cairo-image-surface-private.h"
/**
* cairo_debug_reset_static_data:
*
* Resets all static data within cairo to its original state,
* (ie. identical to the state at the time of program invocation). For
* example, all caches within cairo will be flushed empty.
*
* This function is intended to be useful when using memory-checking
* tools such as valgrind. When valgrind's memcheck analyzes a
* cairo-using program without a call to cairo_debug_reset_static_data(),
* it will report all data reachable via cairo's static objects as
* "still reachable". Calling cairo_debug_reset_static_data() just prior
* to program termination will make it easier to get squeaky clean
* reports from valgrind.
*
* WARNING: It is only safe to call this function when there are no
* active cairo objects remaining, (ie. the appropriate destroy
* functions have been called as necessary). If there are active cairo
* objects, this call is likely to cause a crash, (eg. an assertion
* failure due to a hash table being destroyed when non-empty).
*
* Since: 1.0
**/
void
cairo_debug_reset_static_data (void)
{
CAIRO_MUTEX_INITIALIZE ();
_cairo_scaled_font_map_destroy ();
_cairo_toy_font_face_reset_static_data ();
#if CAIRO_HAS_FT_FONT
_cairo_ft_font_reset_static_data ();
#endif
#if CAIRO_HAS_WIN32_FONT
_cairo_win32_font_reset_static_data ();
#endif
_cairo_intern_string_reset_static_data ();
_cairo_scaled_font_reset_static_data ();
_cairo_pattern_reset_static_data ();
_cairo_clip_reset_static_data ();
_cairo_image_reset_static_data ();
#if CAIRO_HAS_DRM_SURFACE
_cairo_drm_device_reset_static_data ();
#endif
_cairo_default_context_reset_static_data ();
#if CAIRO_HAS_COGL_SURFACE
_cairo_cogl_context_reset_static_data ();
#endif
CAIRO_MUTEX_FINALIZE ();
}
#if HAVE_VALGRIND
void
_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
{
const cairo_image_surface_t *image = (cairo_image_surface_t *) surface;
const uint8_t *bits;
int row, width;
if (surface == NULL)
return;
if (! RUNNING_ON_VALGRIND)
return;
bits = image->data;
switch (image->format) {
case CAIRO_FORMAT_A1:
width = (image->width + 7)/8;
break;
case CAIRO_FORMAT_A8:
width = image->width;
break;
case CAIRO_FORMAT_RGB16_565:
width = image->width*2;
break;
case CAIRO_FORMAT_RGB24:
case CAIRO_FORMAT_RGB30:
case CAIRO_FORMAT_ARGB32:
width = image->width*4;
break;
case CAIRO_FORMAT_INVALID:
default:
/* XXX compute width from pixman bpp */
return;
}
for (row = 0; row < image->height; row++) {
VALGRIND_CHECK_MEM_IS_DEFINED (bits, width);
/* and then silence any future valgrind warnings */
VALGRIND_MAKE_MEM_DEFINED (bits, width);
bits += image->stride;
}
}
#endif
#if 0
void
_cairo_image_surface_write_to_ppm (cairo_image_surface_t *isurf, const char *fn)
{
char *fmt;
if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24)
fmt = "P6";
else if (isurf->format == CAIRO_FORMAT_A8)
fmt = "P5";
else
return;
FILE *fp = fopen(fn, "wb");
if (!fp)
return;
fprintf (fp, "%s %d %d 255\n", fmt,isurf->width, isurf->height);
for (int j = 0; j < isurf->height; j++) {
unsigned char *row = isurf->data + isurf->stride * j;
for (int i = 0; i < isurf->width; i++) {
if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24) {
unsigned char r = *row++;
unsigned char g = *row++;
unsigned char b = *row++;
*row++;
putc(r, fp);
putc(g, fp);
putc(b, fp);
} else {
unsigned char a = *row++;
putc(a, fp);
}
}
}
fclose (fp);
fprintf (stderr, "Wrote %s\n", fn);
}
#endif
static cairo_status_t
_print_move_to (void *closure,
const cairo_point_t *point)
{
fprintf (closure,
" %f %f m",
_cairo_fixed_to_double (point->x),
_cairo_fixed_to_double (point->y));
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_print_line_to (void *closure,
const cairo_point_t *point)
{
fprintf (closure,
" %f %f l",
_cairo_fixed_to_double (point->x),
_cairo_fixed_to_double (point->y));
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_print_curve_to (void *closure,
const cairo_point_t *p1,
const cairo_point_t *p2,
const cairo_point_t *p3)
{
fprintf (closure,
" %f %f %f %f %f %f c",
_cairo_fixed_to_double (p1->x),
_cairo_fixed_to_double (p1->y),
_cairo_fixed_to_double (p2->x),
_cairo_fixed_to_double (p2->y),
_cairo_fixed_to_double (p3->x),
_cairo_fixed_to_double (p3->y));
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_print_close (void *closure)
{
fprintf (closure, " h");
return CAIRO_STATUS_SUCCESS;
}
void
_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
{
cairo_status_t status;
cairo_box_t box;
fprintf (stream,
"path: extents=(%f, %f), (%f, %f)\n",
_cairo_fixed_to_double (path->extents.p1.x),
_cairo_fixed_to_double (path->extents.p1.y),
_cairo_fixed_to_double (path->extents.p2.x),
_cairo_fixed_to_double (path->extents.p2.y));
status = _cairo_path_fixed_interpret (path,
_print_move_to,
_print_line_to,
_print_curve_to,
_print_close,
stream);
assert (status == CAIRO_STATUS_SUCCESS);
if (_cairo_path_fixed_is_box (path, &box)) {
fprintf (stream, "[box (%d, %d), (%d, %d)]",
box.p1.x, box.p1.y, box.p2.x, box.p2.y);
}
printf ("\n");
}
void
_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon)
{
int n;
fprintf (stream,
"polygon: extents=(%f, %f), (%f, %f)\n",
_cairo_fixed_to_double (polygon->extents.p1.x),
_cairo_fixed_to_double (polygon->extents.p1.y),
_cairo_fixed_to_double (polygon->extents.p2.x),
_cairo_fixed_to_double (polygon->extents.p2.y));
if (polygon->num_limits) {
fprintf (stream,
" : limit=(%f, %f), (%f, %f) x %d\n",
_cairo_fixed_to_double (polygon->limit.p1.x),
_cairo_fixed_to_double (polygon->limit.p1.y),
_cairo_fixed_to_double (polygon->limit.p2.x),
_cairo_fixed_to_double (polygon->limit.p2.y),
polygon->num_limits);
}
for (n = 0; n < polygon->num_edges; n++) {
cairo_edge_t *edge = &polygon->edges[n];
fprintf (stream,
" [%d] = [(%f, %f), (%f, %f)], top=%f, bottom=%f, dir=%d\n",
n,
_cairo_fixed_to_double (edge->line.p1.x),
_cairo_fixed_to_double (edge->line.p1.y),
_cairo_fixed_to_double (edge->line.p2.x),
_cairo_fixed_to_double (edge->line.p2.y),
_cairo_fixed_to_double (edge->top),
_cairo_fixed_to_double (edge->bottom),
edge->dir);
}
}

View File

@@ -0,0 +1,68 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Carl D. Worth <cworth@redhat.com>
*/
#ifndef CAIRO_DEFAULT_CONTEXT_PRIVATE_H
#define CAIRO_DEFAULT_CONTEXT_PRIVATE_H
#include "cairo-private.h"
#include "cairo-gstate-private.h"
#include "cairo-path-fixed-private.h"
CAIRO_BEGIN_DECLS
typedef struct _cairo_default_context cairo_default_context_t;
struct _cairo_default_context {
cairo_t base;
cairo_gstate_t *gstate;
cairo_gstate_t gstate_tail[2];
cairo_gstate_t *gstate_freelist;
cairo_path_fixed_t path[1];
};
cairo_private cairo_t *
_cairo_default_context_create (void *target);
cairo_private cairo_status_t
_cairo_default_context_init (cairo_default_context_t *cr, void *target);
cairo_private void
_cairo_default_context_fini (cairo_default_context_t *cr);
CAIRO_END_DECLS
#endif /* CAIRO_DEFAULT_CONTEXT_PRIVATE_H */

Some files were not shown because too many files have changed in this diff Show More